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 @@
import { Quat, Vec2, Vec3, EPSILON } from 'mol-math/linear-algebra';
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 = {
noScroll: true,
......@@ -79,8 +79,8 @@ namespace TrackballControls {
const _zoomStart = Vec2.zero()
const _zoomEnd = Vec2.zero()
// let _touchZoomDistanceStart = 0
// let _touchZoomDistanceEnd = 0
let _touchZoomDistanceStart = 0
let _touchZoomDistanceEnd = 0
const _panStart = Vec2.zero()
const _panEnd = Vec2.zero()
......@@ -156,25 +156,7 @@ namespace TrackballControls {
Vec2.copy(_movePrev, _moveCurr)
}
function zoomCamera () {
// if (_state === STATE.TOUCH_ZOOM_PAN) {
// 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) {
Vec3.scale(_eye, _eye, factor)
......@@ -260,26 +242,26 @@ namespace TrackballControls {
// listeners
function onDrag({ pageX, pageY, buttons, modifiers, started }: DragInput) {
if (started) {
if (buttons === MouseButtonsFlag.Primary) {
function onDrag({ pageX, pageY, buttons, modifiers, isStart }: DragInput) {
if (isStart) {
if (buttons === ButtonsFlag.Primary) {
Vec2.copy(_moveCurr, getMouseOnCircle(pageX, pageY))
Vec2.copy(_movePrev, _moveCurr)
} else if (buttons === MouseButtonsFlag.Auxilary) {
} else if (buttons === ButtonsFlag.Auxilary) {
Vec2.copy(_zoomStart, getMouseOnScreen(pageX, pageY))
Vec2.copy(_zoomEnd, _zoomStart)
} else if (buttons === MouseButtonsFlag.Secondary) {
} else if (buttons === ButtonsFlag.Secondary) {
Vec2.copy(_panStart, getMouseOnScreen(pageX, pageY))
Vec2.copy(_panEnd, _panStart)
}
}
if (buttons === MouseButtonsFlag.Primary) {
if (buttons === ButtonsFlag.Primary) {
Vec2.copy(_movePrev, _moveCurr)
Vec2.copy(_moveCurr, getMouseOnCircle(pageX, pageY))
} else if (buttons === MouseButtonsFlag.Auxilary) {
} else if (buttons === ButtonsFlag.Auxilary) {
Vec2.copy(_zoomEnd, getMouseOnScreen(pageX, pageY))
} else if (buttons === MouseButtonsFlag.Secondary) {
} else if (buttons === ButtonsFlag.Secondary) {
Vec2.copy(_panEnd, getMouseOnScreen(pageX, pageY))
}
}
......@@ -288,81 +270,23 @@ namespace TrackballControls {
_zoomStart[1] -= dy
}
function onPinch({ delta }: PinchInput) {
console.log(delta)
_zoomStart[1] -= delta
function onPinch({ distance, isStart }: PinchInput) {
if (isStart) {
_touchZoomDistanceStart = distance
}
_touchZoomDistanceEnd = distance
// function touchstart(event: TouchEvent ) {
// switch ( event.touches.length ) {
// case 1:
// // _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;
// }
// }
const factor = (_touchZoomDistanceStart / _touchZoomDistanceEnd) * zoomSpeed
_touchZoomDistanceStart = _touchZoomDistanceEnd;
Vec3.scale(_eye, _eye, factor)
}
function dispose() {
if (disposed) return
disposed = true
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
update();
......
......@@ -9,7 +9,6 @@ import { Subject } from 'rxjs';
import { Vec2 } from 'mol-math/linear-algebra';
import toPixels from '../to-pixels'
import TouchPinch from './touch-pinch'
function getButtons(event: MouseEvent | Touch) {
if (typeof event === 'object') {
......@@ -51,7 +50,7 @@ export type ModifiersKeys = {
meta: boolean
}
export const enum MouseButtonsFlag {
export const enum ButtonsFlag {
/** No button or un-initialized */
None = 0x0,
/** Primary button (usually left) */
......@@ -78,7 +77,7 @@ export type DragInput = {
dy: number,
pageX: number,
pageY: number,
started: boolean
isStart: boolean
} & BaseInput
export type WheelInput = {
......@@ -96,7 +95,8 @@ export type ClickInput = {
export type PinchInput = {
delta: number,
distance: number
distance: number,
isStart: boolean
}
const enum DraggingState {
......@@ -142,8 +142,6 @@ namespace InputObserver {
meta: false
}
// const touchPinch = TouchPinch.create(element)
let dragging: DraggingState = DraggingState.Stopped
let disposed = false
let buttons = 0
......@@ -183,10 +181,6 @@ namespace InputObserver {
element.addEventListener('touchmove', onTouchMove 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('keyup', handleMods as EventListener)
element.addEventListener('keydown', handleMods as EventListener)
......@@ -197,8 +191,6 @@ namespace InputObserver {
if (disposed) return
disposed = true
// touchPinch.dispose()
element.removeEventListener( 'contextmenu', onContextMenu, false )
element.removeEventListener('wheel', onMouseWheel, false)
......@@ -260,79 +252,43 @@ namespace InputObserver {
function onTouchStart (ev: TouchEvent) {
preventDefault(ev)
console.log('onTouchStart', ev)
if (ev.touches.length === 1) {
buttons = MouseButtonsFlag.Primary
buttons = ButtonsFlag.Primary
onPointerDown(ev.touches[0])
} else if (ev.touches.length >= 2) {
buttons = MouseButtonsFlag.Secondary
buttons = ButtonsFlag.Secondary
onPointerDown(getCenterTouch(ev))
let lastTouchDistance = getTouchDistance(ev)
pinch.next({ distance: lastTouchDistance, delta: 0 })
pinch.next({ distance: lastTouchDistance, delta: 0, isStart: true })
}
}
function onTouchEnd (ev: TouchEvent) {
preventDefault(ev)
console.log('onTouchEnd', ev)
}
function onTouchMove (ev: TouchEvent) {
preventDefault(ev)
if (ev.touches.length === 1) {
buttons = MouseButtonsFlag.Primary
buttons = ButtonsFlag.Primary
onPointerMove(ev.touches[0])
} else if (ev.touches.length >= 2) {
buttons = MouseButtonsFlag.Secondary
onPointerDown(getCenterTouch(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
}
// 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) {
preventDefault(ev)
......@@ -370,27 +326,21 @@ namespace InputObserver {
const { pageX, pageY } = ev
const [ x, y ] = pointerEnd
console.log('click', { x, y, pageX, pageY, buttons, modifiers })
click.next({ x, y, pageX, pageY, buttons, modifiers })
}
}
function onPointerMove (ev: PointerEvent) {
eventOffset(pointerEnd, ev)
// if (pinch && isPinching()) {
// Vec2.copy(pointerStart, pointerEnd)
// return
// }
if (dragging === DraggingState.Stopped) return
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 [ x, y ] = pointerEnd
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, started })
drag.next({ x, y, dx, dy, pageX, pageY, buttons, modifiers, isStart })
Vec2.copy(pointerStart, pointerEnd)
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.
Please register or to comment