Browse Source

wip, seperating inputs from controls

Alexander Rose 7 years ago
parent
commit
05b5554e23
3 changed files with 43 additions and 357 deletions
  1. 23 99
      src/mol-gl/controls/trackball.ts
  2. 20 70
      src/mol-util/input/input-observer.ts
  3. 0 188
      src/mol-util/input/touch-pinch.ts

+ 23 - 99
src/mol-gl/controls/trackball.ts

@@ -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,26 +156,8 @@ 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
+            const factor = 1.0 + (_zoomEnd[1] - _zoomStart[1]) * zoomSpeed
             if (factor !== 1.0 && factor > 0.0) {
                 Vec3.scale(_eye, _eye, factor)
             }
@@ -183,7 +165,7 @@ namespace TrackballControls {
             if (staticMoving) {
                 Vec2.copy(_zoomStart, _zoomEnd)
             } else {
-                _zoomStart[1] += ( _zoomEnd[1] - _zoomStart[1] ) * dynamicDampingFactor
+                _zoomStart[1] += (_zoomEnd[1] - _zoomStart[1]) * dynamicDampingFactor
             }
         }
 
@@ -231,7 +213,7 @@ namespace TrackballControls {
         }
 
         function update() {
-            Vec3.sub( _eye, object.position, target)
+            Vec3.sub(_eye, object.position, target)
 
             rotateCamera()
             zoomCamera()
@@ -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();
 

+ 20 - 70
src/mol-util/input/input-observer.ts

@@ -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

+ 0 - 188
src/mol-util/input/touch-pinch.ts

@@ -1,188 +0,0 @@
-/**
- * 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