Skip to content
Snippets Groups Projects
Commit 05b5554e authored by Alexander Rose's avatar Alexander Rose
Browse files

wip, seperating inputs from controls

parent d4670e0e
No related branches found
No related tags found
No related merge requests found
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
import { Quat, Vec2, Vec3, EPSILON } from 'mol-math/linear-algebra'; import { Quat, Vec2, Vec3, EPSILON } from 'mol-math/linear-algebra';
import { cameraLookAt, Viewport } from '../camera/util'; import { cameraLookAt, Viewport } from '../camera/util';
import InputObserver, { DragInput, WheelInput, MouseButtonsFlag, PinchInput } from 'mol-util/input/input-observer'; import InputObserver, { DragInput, WheelInput, ButtonsFlag, PinchInput } from 'mol-util/input/input-observer';
export const DefaultTrackballControlsProps = { export const DefaultTrackballControlsProps = {
noScroll: true, noScroll: true,
...@@ -79,8 +79,8 @@ namespace TrackballControls { ...@@ -79,8 +79,8 @@ namespace TrackballControls {
const _zoomStart = Vec2.zero() const _zoomStart = Vec2.zero()
const _zoomEnd = Vec2.zero() const _zoomEnd = Vec2.zero()
// let _touchZoomDistanceStart = 0 let _touchZoomDistanceStart = 0
// let _touchZoomDistanceEnd = 0 let _touchZoomDistanceEnd = 0
const _panStart = Vec2.zero() const _panStart = Vec2.zero()
const _panEnd = Vec2.zero() const _panEnd = Vec2.zero()
...@@ -156,26 +156,8 @@ namespace TrackballControls { ...@@ -156,26 +156,8 @@ namespace TrackballControls {
Vec2.copy(_movePrev, _moveCurr) Vec2.copy(_movePrev, _moveCurr)
} }
function zoomCamera () { function zoomCamera () {
// if (_state === STATE.TOUCH_ZOOM_PAN) { const factor = 1.0 + (_zoomEnd[1] - _zoomStart[1]) * zoomSpeed
// const factor = _touchZoomDistanceStart / _touchZoomDistanceEnd
// _touchZoomDistanceStart = _touchZoomDistanceEnd;
// Vec3.scale(_eye, _eye, factor)
// } else {
// const factor = 1.0 + ( _zoomEnd[1] - _zoomStart[1] ) * zoomSpeed
// if (factor !== 1.0 && factor > 0.0) {
// Vec3.scale(_eye, _eye, factor)
// }
// if (staticMoving) {
// Vec2.copy(_zoomStart, _zoomEnd)
// } else {
// _zoomStart[1] += ( _zoomEnd[1] - _zoomStart[1] ) * dynamicDampingFactor
// }
// }
const factor = 1.0 + ( _zoomEnd[1] - _zoomStart[1] ) * zoomSpeed
if (factor !== 1.0 && factor > 0.0) { if (factor !== 1.0 && factor > 0.0) {
Vec3.scale(_eye, _eye, factor) Vec3.scale(_eye, _eye, factor)
} }
...@@ -183,7 +165,7 @@ namespace TrackballControls { ...@@ -183,7 +165,7 @@ namespace TrackballControls {
if (staticMoving) { if (staticMoving) {
Vec2.copy(_zoomStart, _zoomEnd) Vec2.copy(_zoomStart, _zoomEnd)
} else { } else {
_zoomStart[1] += ( _zoomEnd[1] - _zoomStart[1] ) * dynamicDampingFactor _zoomStart[1] += (_zoomEnd[1] - _zoomStart[1]) * dynamicDampingFactor
} }
} }
...@@ -231,7 +213,7 @@ namespace TrackballControls { ...@@ -231,7 +213,7 @@ namespace TrackballControls {
} }
function update() { function update() {
Vec3.sub( _eye, object.position, target) Vec3.sub(_eye, object.position, target)
rotateCamera() rotateCamera()
zoomCamera() zoomCamera()
...@@ -260,26 +242,26 @@ namespace TrackballControls { ...@@ -260,26 +242,26 @@ namespace TrackballControls {
// listeners // listeners
function onDrag({ pageX, pageY, buttons, modifiers, started }: DragInput) { function onDrag({ pageX, pageY, buttons, modifiers, isStart }: DragInput) {
if (started) { if (isStart) {
if (buttons === MouseButtonsFlag.Primary) { if (buttons === ButtonsFlag.Primary) {
Vec2.copy(_moveCurr, getMouseOnCircle(pageX, pageY)) Vec2.copy(_moveCurr, getMouseOnCircle(pageX, pageY))
Vec2.copy(_movePrev, _moveCurr) Vec2.copy(_movePrev, _moveCurr)
} else if (buttons === MouseButtonsFlag.Auxilary) { } else if (buttons === ButtonsFlag.Auxilary) {
Vec2.copy(_zoomStart, getMouseOnScreen(pageX, pageY)) Vec2.copy(_zoomStart, getMouseOnScreen(pageX, pageY))
Vec2.copy(_zoomEnd, _zoomStart) Vec2.copy(_zoomEnd, _zoomStart)
} else if (buttons === MouseButtonsFlag.Secondary) { } else if (buttons === ButtonsFlag.Secondary) {
Vec2.copy(_panStart, getMouseOnScreen(pageX, pageY)) Vec2.copy(_panStart, getMouseOnScreen(pageX, pageY))
Vec2.copy(_panEnd, _panStart) Vec2.copy(_panEnd, _panStart)
} }
} }
if (buttons === MouseButtonsFlag.Primary) { if (buttons === ButtonsFlag.Primary) {
Vec2.copy(_movePrev, _moveCurr) Vec2.copy(_movePrev, _moveCurr)
Vec2.copy(_moveCurr, getMouseOnCircle(pageX, pageY)) Vec2.copy(_moveCurr, getMouseOnCircle(pageX, pageY))
} else if (buttons === MouseButtonsFlag.Auxilary) { } else if (buttons === ButtonsFlag.Auxilary) {
Vec2.copy(_zoomEnd, getMouseOnScreen(pageX, pageY)) Vec2.copy(_zoomEnd, getMouseOnScreen(pageX, pageY))
} else if (buttons === MouseButtonsFlag.Secondary) { } else if (buttons === ButtonsFlag.Secondary) {
Vec2.copy(_panEnd, getMouseOnScreen(pageX, pageY)) Vec2.copy(_panEnd, getMouseOnScreen(pageX, pageY))
} }
} }
...@@ -288,81 +270,23 @@ namespace TrackballControls { ...@@ -288,81 +270,23 @@ namespace TrackballControls {
_zoomStart[1] -= dy _zoomStart[1] -= dy
} }
function onPinch({ delta }: PinchInput) { function onPinch({ distance, isStart }: PinchInput) {
console.log(delta) if (isStart) {
_zoomStart[1] -= delta _touchZoomDistanceStart = distance
} }
_touchZoomDistanceEnd = distance
// function touchstart(event: TouchEvent ) { const factor = (_touchZoomDistanceStart / _touchZoomDistanceEnd) * zoomSpeed
// switch ( event.touches.length ) { _touchZoomDistanceStart = _touchZoomDistanceEnd;
// case 1: Vec3.scale(_eye, _eye, factor)
// // _state = STATE.TOUCH_ROTATE; }
// Vec2.copy(_moveCurr, getMouseOnCircle(event.touches[0].pageX, event.touches[0].pageY))
// Vec2.copy(_movePrev, _moveCurr)
// break;
// default: // 2 or more
// // _state = STATE.TOUCH_ZOOM_PAN;
// const dx = event.touches[0].pageX - event.touches[1].pageX;
// const dy = event.touches[0].pageY - event.touches[1].pageY;
// _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt(dx * dx + dy * dy);
// const x = ( event.touches[0].pageX + event.touches[1].pageX) / 2;
// const y = ( event.touches[0].pageY + event.touches[1].pageY) / 2;
// Vec2.copy(_panStart, getMouseOnScreen(x, y))
// Vec2.copy(_panEnd, _panStart)
// break;
// }
// }
// function touchmove(event: TouchEvent) {
// event.preventDefault();
// event.stopPropagation();
// switch ( event.touches.length ) {
// case 1:
// Vec2.copy(_movePrev, _moveCurr)
// Vec2.copy(_moveCurr, getMouseOnCircle(event.touches[0].pageX, event.touches[0].pageY))
// break;
// default: // 2 or more
// const dx = event.touches[0].pageX - event.touches[1].pageX;
// const dy = event.touches[0].pageY - event.touches[1].pageY;
// _touchZoomDistanceEnd = Math.sqrt(dx * dx + dy * dy);
// const x = (event.touches[0].pageX + event.touches[1].pageX) / 2;
// const y = (event.touches[0].pageY + event.touches[1].pageY) / 2;
// Vec2.copy(_panEnd, getMouseOnScreen(x, y))
// break;
// }
// }
// function touchend(event: TouchEvent) {
// switch ( event.touches.length ) {
// case 0:
// // _state = STATE.NONE;
// break;
// case 1:
// // _state = STATE.TOUCH_ROTATE;
// Vec2.copy(_moveCurr, getMouseOnCircle(event.touches[0].pageX, event.touches[0].pageY))
// Vec2.copy(_movePrev, _moveCurr)
// break;
// }
// }
function dispose() { function dispose() {
if (disposed) return if (disposed) return
disposed = true disposed = true
input.dispose() input.dispose()
// element.removeEventListener( 'touchstart', touchstart as any, false );
// element.removeEventListener( 'touchend', touchend as any, false );
// element.removeEventListener( 'touchmove', touchmove as any, false );
} }
// element.addEventListener( 'touchstart', touchstart as any, false );
// element.addEventListener( 'touchend', touchend as any, false );
// element.addEventListener( 'touchmove', touchmove as any, false );
// force an update at start // force an update at start
update(); update();
......
...@@ -9,7 +9,6 @@ import { Subject } from 'rxjs'; ...@@ -9,7 +9,6 @@ import { Subject } from 'rxjs';
import { Vec2 } from 'mol-math/linear-algebra'; import { Vec2 } from 'mol-math/linear-algebra';
import toPixels from '../to-pixels' import toPixels from '../to-pixels'
import TouchPinch from './touch-pinch'
function getButtons(event: MouseEvent | Touch) { function getButtons(event: MouseEvent | Touch) {
if (typeof event === 'object') { if (typeof event === 'object') {
...@@ -51,7 +50,7 @@ export type ModifiersKeys = { ...@@ -51,7 +50,7 @@ export type ModifiersKeys = {
meta: boolean meta: boolean
} }
export const enum MouseButtonsFlag { export const enum ButtonsFlag {
/** No button or un-initialized */ /** No button or un-initialized */
None = 0x0, None = 0x0,
/** Primary button (usually left) */ /** Primary button (usually left) */
...@@ -78,7 +77,7 @@ export type DragInput = { ...@@ -78,7 +77,7 @@ export type DragInput = {
dy: number, dy: number,
pageX: number, pageX: number,
pageY: number, pageY: number,
started: boolean isStart: boolean
} & BaseInput } & BaseInput
export type WheelInput = { export type WheelInput = {
...@@ -96,7 +95,8 @@ export type ClickInput = { ...@@ -96,7 +95,8 @@ export type ClickInput = {
export type PinchInput = { export type PinchInput = {
delta: number, delta: number,
distance: number distance: number,
isStart: boolean
} }
const enum DraggingState { const enum DraggingState {
...@@ -142,8 +142,6 @@ namespace InputObserver { ...@@ -142,8 +142,6 @@ namespace InputObserver {
meta: false meta: false
} }
// const touchPinch = TouchPinch.create(element)
let dragging: DraggingState = DraggingState.Stopped let dragging: DraggingState = DraggingState.Stopped
let disposed = false let disposed = false
let buttons = 0 let buttons = 0
...@@ -183,10 +181,6 @@ namespace InputObserver { ...@@ -183,10 +181,6 @@ namespace InputObserver {
element.addEventListener('touchmove', onTouchMove as any, false) element.addEventListener('touchmove', onTouchMove as any, false)
element.addEventListener('touchend', onTouchEnd as any, false) element.addEventListener('touchend', onTouchEnd as any, false)
// touchPinch.place.subscribe(onPinchPlace)
// touchPinch.lift.subscribe(onPinchLift)
// touchPinch.change.subscribe(onPinchChange)
element.addEventListener('blur', handleBlur) element.addEventListener('blur', handleBlur)
element.addEventListener('keyup', handleMods as EventListener) element.addEventListener('keyup', handleMods as EventListener)
element.addEventListener('keydown', handleMods as EventListener) element.addEventListener('keydown', handleMods as EventListener)
...@@ -197,8 +191,6 @@ namespace InputObserver { ...@@ -197,8 +191,6 @@ namespace InputObserver {
if (disposed) return if (disposed) return
disposed = true disposed = true
// touchPinch.dispose()
element.removeEventListener( 'contextmenu', onContextMenu, false ) element.removeEventListener( 'contextmenu', onContextMenu, false )
element.removeEventListener('wheel', onMouseWheel, false) element.removeEventListener('wheel', onMouseWheel, false)
...@@ -260,79 +252,43 @@ namespace InputObserver { ...@@ -260,79 +252,43 @@ namespace InputObserver {
function onTouchStart (ev: TouchEvent) { function onTouchStart (ev: TouchEvent) {
preventDefault(ev) preventDefault(ev)
console.log('onTouchStart', ev)
if (ev.touches.length === 1) { if (ev.touches.length === 1) {
buttons = MouseButtonsFlag.Primary buttons = ButtonsFlag.Primary
onPointerDown(ev.touches[0]) onPointerDown(ev.touches[0])
} else if (ev.touches.length >= 2) { } else if (ev.touches.length >= 2) {
buttons = MouseButtonsFlag.Secondary buttons = ButtonsFlag.Secondary
onPointerDown(getCenterTouch(ev)) onPointerDown(getCenterTouch(ev))
let lastTouchDistance = getTouchDistance(ev) pinch.next({ distance: lastTouchDistance, delta: 0, isStart: true })
pinch.next({ distance: lastTouchDistance, delta: 0 })
} }
} }
function onTouchEnd (ev: TouchEvent) { function onTouchEnd (ev: TouchEvent) {
preventDefault(ev) preventDefault(ev)
console.log('onTouchEnd', ev)
} }
function onTouchMove (ev: TouchEvent) { function onTouchMove (ev: TouchEvent) {
preventDefault(ev) preventDefault(ev)
if (ev.touches.length === 1) { if (ev.touches.length === 1) {
buttons = MouseButtonsFlag.Primary buttons = ButtonsFlag.Primary
onPointerMove(ev.touches[0]) onPointerMove(ev.touches[0])
} else if (ev.touches.length >= 2) { } else if (ev.touches.length >= 2) {
buttons = MouseButtonsFlag.Secondary
onPointerDown(getCenterTouch(ev))
const touchDistance = getTouchDistance(ev) const touchDistance = getTouchDistance(ev)
pinch.next({ delta: lastTouchDistance - touchDistance, distance: touchDistance }) if (lastTouchDistance - touchDistance < 4) {
buttons = ButtonsFlag.Secondary
onPointerMove(getCenterTouch(ev))
} else {
pinch.next({
delta: lastTouchDistance - touchDistance,
distance: touchDistance,
isStart: false
})
}
lastTouchDistance = touchDistance lastTouchDistance = touchDistance
} }
// if (dragging === DraggingState.Stopped || isPinching()) return
// // find currently active finger
// for (let i = 0; i < ev.changedTouches.length; i++) {
// const changed = ev.changedTouches[i]
// const idx = touchPinch.indexOfTouch(changed)
// if (idx !== -1) {
// onInputMove(changed)
// break
// }
// }
} }
// function onPinchPlace ({ newTouch, oldTouch }: { newTouch?: Touch, oldTouch?: Touch }) {
// dragging = isPinching() ? DraggingState.Stopped : DraggingState.Started
// if (dragging === DraggingState.Started) {
// const firstFinger = oldTouch || newTouch
// if (firstFinger) onInputDown(firstFinger)
// }
// }
// function onPinchLift ({ removed, otherTouch }: { removed?: Touch, otherTouch?: Touch }) {
// // if either finger is down, consider it dragging
// const sum = touchPinch.fingers.reduce((sum, item) => sum + (item ? 1 : 0), 0)
// dragging = sum >= 1 ? DraggingState.Moving : DraggingState.Stopped
// if (dragging && otherTouch) {
// eventOffset(mouseStart, otherTouch, element)
// }
// }
// function isPinching () {
// return touchPinch.pinching
// }
// function onPinchChange ({ currentDistance, lastDistance }: { currentDistance: number, lastDistance: number }) {
// pinch.next({ delta: currentDistance - lastDistance })
// }
function onMouseDown (ev: MouseEvent) { function onMouseDown (ev: MouseEvent) {
preventDefault(ev) preventDefault(ev)
...@@ -370,27 +326,21 @@ namespace InputObserver { ...@@ -370,27 +326,21 @@ namespace InputObserver {
const { pageX, pageY } = ev const { pageX, pageY } = ev
const [ x, y ] = pointerEnd const [ x, y ] = pointerEnd
console.log('click', { x, y, pageX, pageY, buttons, modifiers })
click.next({ x, y, pageX, pageY, buttons, modifiers }) click.next({ x, y, pageX, pageY, buttons, modifiers })
} }
} }
function onPointerMove (ev: PointerEvent) { function onPointerMove (ev: PointerEvent) {
eventOffset(pointerEnd, ev) eventOffset(pointerEnd, ev)
// if (pinch && isPinching()) {
// Vec2.copy(pointerStart, pointerEnd)
// return
// }
if (dragging === DraggingState.Stopped) return if (dragging === DraggingState.Stopped) return
Vec2.div(pointerDelta, Vec2.sub(pointerDelta, pointerEnd, pointerStart), getClientSize(rectSize)) Vec2.div(pointerDelta, Vec2.sub(pointerDelta, pointerEnd, pointerStart), getClientSize(rectSize))
const started = dragging === DraggingState.Started const isStart = dragging === DraggingState.Started
const { pageX, pageY } = ev const { pageX, pageY } = ev
const [ x, y ] = pointerEnd const [ x, y ] = pointerEnd
const [ dx, dy ] = pointerDelta const [ dx, dy ] = pointerDelta
// console.log({ x, y, dx, dy, pageX, pageY, buttons, modifiers, started }) drag.next({ x, y, dx, dy, pageX, pageY, buttons, modifiers, isStart })
drag.next({ x, y, dx, dy, pageX, pageY, buttons, modifiers, started })
Vec2.copy(pointerStart, pointerEnd) Vec2.copy(pointerStart, pointerEnd)
dragging = DraggingState.Moving dragging = DraggingState.Moving
......
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
/*
* This code has been modified (use TypeScript, RxJS) from https://github.com/Jam3/touch-pinch,
* copyright (c) 2014 Matt DesLauriers. MIT License
*/
import { Subject } from 'rxjs';
import { Vec2 } from 'mol-math/linear-algebra';
import { eventOffset } from './event-offset'
interface Finger {
position: Vec2,
touch?: Touch
}
function Finger (): Finger {
return {
position: Vec2.zero(),
touch: undefined
}
}
interface TouchPinch {
pinching: boolean
fingers: (Finger|undefined)[]
indexOfTouch: (touch: Touch) => number
start: Subject<number>
end: Subject<void>
place: Subject<{ newTouch?: Touch, oldTouch?: Touch}>
change: Subject<{ currentDistance: number, lastDistance: number }>
lift: Subject<{ removed: Touch, otherTouch?: Touch }>
dispose: () => void
}
namespace TouchPinch {
export function create (target: Element): TouchPinch {
const fingers: (Finger|undefined)[] = []
let activeCount = 0
let lastDistance = 0
let ended = false
let disposed = false
const start = new Subject<number>()
const end = new Subject<void>()
const place = new Subject<{ newTouch?: Touch, oldTouch?: Touch}>()
const change = new Subject<{ currentDistance: number, lastDistance: number }>()
const lift = new Subject<{ removed: Touch, otherTouch?: Touch }>()
target.addEventListener('touchstart', onTouchStart as any, false)
target.addEventListener('touchmove', onTouchMove as any, false)
target.addEventListener('touchend', onTouchRemoved as any, false)
target.addEventListener('touchcancel', onTouchRemoved as any, false)
return {
get pinching() { return activeCount === 2 },
fingers,
indexOfTouch,
start,
end,
place,
change,
lift,
dispose
}
function indexOfTouch (touch: Touch) {
const id = touch.identifier
for (let i = 0; i < fingers.length; i++) {
const finger = fingers[i]
if (finger && finger.touch && finger.touch.identifier === id) {
return i
}
}
return -1
}
function dispose () {
if (disposed) return
disposed = true
activeCount = 0
fingers[0] = undefined
fingers[1] = undefined
lastDistance = 0
ended = false
target.removeEventListener('touchstart', onTouchStart as any, false)
target.removeEventListener('touchmove', onTouchMove as any, false)
target.removeEventListener('touchend', onTouchRemoved as any, false)
target.removeEventListener('touchcancel', onTouchRemoved as any, false)
}
function onTouchStart (ev: TouchEvent) {
for (let i = 0; i < ev.changedTouches.length; i++) {
const newTouch = ev.changedTouches[i]
const idx = indexOfTouch(newTouch)
if (idx === -1 && activeCount < 2) {
const first = activeCount === 0
// newest and previous finger (previous may be undefined)
const newIndex = fingers[0] ? 1 : 0
const oldIndex = fingers[0] ? 0 : 1
const newFinger = Finger()
// add to stack
fingers[newIndex] = newFinger
activeCount++
// update touch event & position
newFinger.touch = newTouch
eventOffset(newFinger.position, newTouch, target)
const finger = fingers[oldIndex]
const oldTouch = finger ? finger.touch : undefined
place.next({ newTouch, oldTouch })
if (!first) {
const initialDistance = computeDistance()
ended = false
start.next(initialDistance)
lastDistance = initialDistance
}
}
}
}
function onTouchMove (ev: TouchEvent) {
let changed = false
for (let i = 0; i < ev.changedTouches.length; i++) {
const movedTouch = ev.changedTouches[i]
const idx = indexOfTouch(movedTouch)
if (idx !== -1) {
const finger = fingers[idx]
if (finger) {
changed = true
finger.touch = movedTouch // avoid caching touches
eventOffset(finger.position, movedTouch, target)
}
}
}
if (activeCount === 2 && changed) {
const currentDistance = computeDistance()
change.next({ currentDistance, lastDistance })
lastDistance = currentDistance
}
}
function onTouchRemoved (ev: TouchEvent) {
for (let i = 0; i < ev.changedTouches.length; i++) {
const removed = ev.changedTouches[i]
const idx = indexOfTouch(removed)
if (idx !== -1) {
fingers[idx] = undefined
activeCount--
const otherIdx = idx === 0 ? 1 : 0
const finger = fingers[otherIdx]
if (finger) {
const otherTouch = finger ? finger.touch : undefined
lift.next({ removed, otherTouch })
}
}
}
if (!ended && activeCount !== 2) {
ended = true
end.next()
}
}
function computeDistance () {
const [ f1, f2 ] = fingers
return (f1 && f2) ? Vec2.distance(f1.position, f2.position) : 0
}
}
}
export default TouchPinch
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment