Selaa lähdekoodia

Merge pull request #284 from Eucly2/master

Add pinch
deltakosh 11 vuotta sitten
vanhempi
commit
80d20e4daa
1 muutettua tiedostoa jossa 96 lisäystä ja 2 poistoa
  1. 96 2
      Babylon/Cameras/babylon.arcRotateCamera.ts

+ 96 - 2
Babylon/Cameras/babylon.arcRotateCamera.ts

@@ -47,6 +47,19 @@
         private _previousAlpha: number;
         private _previousBeta: number;
         private _previousRadius: number;
+		
+	// Pinch
+	// value for pinch step scaling
+	// set to 20 by default
+	public pinchPrecision = 20;
+	// Event for pinch
+	private _touchStart: (e: PointerEvent) => void;
+	private _touchMove: (e: PointerEvent) => void;
+	private _touchEnd: (e: PointerEvent) => void;
+	// Method for pinch
+	private _pinchStart: (e: PointerEvent) => void;
+	private _pinchMove: (e: PointerEvent) => void;
+	private _pinchEnd: (e: PointerEvent) => void;
 
         constructor(name: string, public alpha: number, public beta: number, public radius: number, public target: any, scene: Scene) {
             super(name, BABYLON.Vector3.Zero(), scene);
@@ -93,7 +106,12 @@
         public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
             var previousPosition;
             var pointerId;
-
+	    // to know if pinch started
+	    var pinchStarted = false;
+	    // two pinch point on X
+	    // that will use for find if user action is pinch open or pinch close
+	    var pinchPointX1, pinchPointX2;
+			
             if (this._attachedElement) {
                 return;
             }
@@ -137,6 +155,11 @@
                     if (pointerId !== evt.pointerId) {
                         return;
                     }
+					
+		    // return pinch is started
+		    if (pinchStarted){
+                        return;
+                    }
 
                     var offsetX = evt.clientX - previousPosition.x;
                     var offsetY = evt.clientY - previousPosition.y;
@@ -158,6 +181,11 @@
                     if (!engine.isPointerLock) {
                         return;
                     }
+					
+		    // return pinch is started
+		    if (pinchStarted){
+                        return;
+                    }
 
                     var offsetX = evt.movementX || evt.mozMovementX || evt.webkitMovementX || evt.msMovementX || 0;
                     var offsetY = evt.movementY || evt.mozMovementY || evt.webkitMovementY || evt.msMovementY || 0;
@@ -264,6 +292,64 @@
                     previousPosition = null;
                     pointerId = null;
                 };
+				
+		this._touchStart = event => {
+                    if (event.touches.length == 2) {
+                        //-- start pinch if two fingers on the screen
+                        pinchStarted = true;
+                        this._pinchStart(event);
+                    } 
+                };
+		this._touchMove = event => {
+                    if (pinchStarted) {
+                        //-- make scaling
+                        this._pinchMove(event);
+                    }
+                };
+		this._touchEnd = event => {
+                    if (pinchStarted) {
+                        //-- end of pinch
+                        this._pinchEnd(event);
+                    } 
+                };
+				
+		this._pinchStart = event => {
+                    // save origin touch point
+                    pinchPointX1 = event.touches[0].clientX;
+                    pinchPointX2 = event.touches[1].clientX;
+                    // block the camera 
+                    // if not it rotate around target during pinch
+                    pinchStarted = true;
+                };
+		this._pinchMove = event => {
+                    // variable for new camera's radius
+                    var delta = 0;
+                    // variables to know if pinch open or pinch close
+                    var direction = 1;
+                    var distanceXOrigine, distanceXNow;
+                    
+                    if (event.touches.length != 2)
+                        return;
+                    // calculate absolute distances of the two fingers
+                    distanceXOrigine = Math.abs(pinchPointX1 - pinchPointX2);
+                    distanceXNow = Math.abs(event.touches[0].clientX - event.touches[1].clientX);
+                    
+                    // if distanceXNow < distanceXOrigine -> pinch close so direction = -1
+                    if (distanceXNow < distanceXOrigine) {
+                        direction = -1;
+                    }
+                    // calculate new radius
+                    delta = (this.pinchPrecision / (this.wheelPrecision * 40)) * direction;
+                    // set new radius
+                    this.inertialRadiusOffset += delta;
+                    // save origin touch point
+                    pinchPointX1 = event.touches[0].clientX;
+                    pinchPointX2 = event.touches[1].clientX;
+                };
+				this._pinchEnd = event => {
+                    // cancel pinch and deblock camera rotation
+                    pinchStarted = false;
+                };
             }
 
             element.addEventListener(eventPrefix + "down", this._onPointerDown, false);
@@ -275,6 +361,10 @@
             element.addEventListener("MSGestureChange", this._onGesture, false);
             element.addEventListener('mousewheel', this._wheel, false);
             element.addEventListener('DOMMouseScroll', this._wheel, false);
+	    // pinch
+            element.addEventListener('touchstart', this._touchStart, false);
+            element.addEventListener('touchmove', this._touchMove, false);
+            element.addEventListener('touchend', this._touchEnd, false);
 
             Tools.RegisterTopRootEvents([
                 { name: "keydown", handler: this._onKeyDown },
@@ -297,6 +387,10 @@
             element.removeEventListener("MSGestureChange", this._onGesture);
             element.removeEventListener('mousewheel', this._wheel);
             element.removeEventListener('DOMMouseScroll', this._wheel);
+	    // pinch
+            element.removeEventListener('touchstart', this._touchStart);
+            element.removeEventListener('touchmove', this._touchMove);
+            element.removeEventListener('touchend', this._touchEnd);
 
             Tools.UnregisterTopRootEvents([
                 { name: "keydown", handler: this._onKeyDown },
@@ -455,4 +549,4 @@
             this.maxZ = distance * 2;
         }
     }
-} 
+}