private void computeZoom(EventLayer eventLayer, ref bool didGesture, Finger finger1, Finger finger2, ref Vector2 finger1Vec, ref Vector2 finger2Vec) { Vector2 finger1Pos = new Vector2(finger1.NrmlX, finger1.NrmlY); Vector2 finger2Pos = new Vector2(finger2.NrmlX, finger2.NrmlY); float currentPinchDistance = (finger1Pos - finger2Pos).length2(); Vector2 vectorSum = finger1Vec - finger2Vec; momentumDirection = 1.0f; zoomDelta = vectorSum.length(); momentum = zoomDelta; deceleration = momentum / decelerationTime; if (currentPinchDistance > lastPinchDistance) { zoomDelta = -zoomDelta; momentumDirection = -1.0f; } didGesture = true; lastPinchDistance = currentPinchDistance; if (!gestureStarted) { gestureStarted = true; if (GestureStarted != null) { GestureStarted.Invoke(eventLayer, this); } } if (Zoom != null) { Zoom.Invoke(eventLayer, this); } }
protected internal override void update(EventLayer eventLayer, bool allowProcessing, Clock clock) { var touches = eventLayer.EventManager.Touches; var fingers = touches.Fingers; if (fingers.Count == fingerCount) { Vector2 primaryFingerVec = new Vector2(fingers[0].PixelDeltaX, fingers[0].PixelDeltaY); float primaryFingerLen = primaryFingerVec.length(); Vector2 longestLengthVec = primaryFingerVec; float longestLength = primaryFingerLen; if (primaryFingerLen > 0) { bool allVectorsSameDirection = true; for (int i = 1; i < fingerCount && allVectorsSameDirection; ++i) { Vector2 testFingerVec = new Vector2(fingers[i].PixelDeltaX, fingers[i].PixelDeltaY); float testFingerLen = testFingerVec.length(); if (testFingerLen > 0) { float cosTheta = primaryFingerVec.dot(ref testFingerVec) / (primaryFingerLen * testFingerLen); if (cosTheta > 0.5f) { if (testFingerLen > longestLength) { longestLengthVec = testFingerVec; longestLength = testFingerLen; } } else { allVectorsSameDirection = false; } } } if (allVectorsSameDirection) { DeltaX = longestLengthVec.x; DeltaY = longestLengthVec.y; AbsoluteX = fingers[0].PixelX; AbsoluteY = fingers[0].PixelY; if (!gestureStarted) { cancelMomentum(); gestureStarted = true; if (GestureStarted != null) { GestureStarted.Invoke(eventLayer, this); } } didGesture = true; averageSpeed[averageSpeedCursor] = longestLengthVec; averageSpeedCursor++; averageSpeedCursor %= averageSpeed.Length; //Make sure to fire event last so momentum can be canceled if needed if (Dragged != null) { Dragged.Invoke(eventLayer, this); } } } else if (gestureStarted) { //If we have done the gesture once and the correct number of fingers are down, keep reporting that we did the gesture didGesture = true; } } if (!didGesture) { if (gestureStarted) { momentumStarted = true; momentum = new IntVector2(0, 0); for (int i = 0; i < averageSpeed.Length; ++i) { momentum += averageSpeed[i]; } momentum /= averageSpeed.Length; momentumDirection = new Vector2(1.0f, 1.0f); if (momentum.x < 0.0f) { momentum.x = -momentum.x; momentumDirection.x = -1.0f; } if (momentum.y < 0.0f) { momentum.y = -momentum.y; momentumDirection.y = -1.0f; } if (momentum.x < minimumMomentum) { momentum.x = 0.0f; } if (momentum.y < minimumMomentum) { momentum.y = 0.0f; } deceleration = momentum / decelerationTime; //Important to fire event last so momentum can be canceled if needed if (MomentumStarted != null) { MomentumStarted(eventLayer, this); } } gestureStarted = false; if (momentum.length2() != 0.0f) { momentum -= deceleration * clock.DeltaSeconds; if (momentum.x < 0.0f) { momentum.x = 0.0f; } if (momentum.y <= 0.0f) { momentum.y = 0.0f; } Vector2 finalMomentum = momentum * momentumDirection; DeltaX = finalMomentum.x; DeltaY = finalMomentum.y; if (Dragged != null) { Dragged.Invoke(eventLayer, this); } } else if (momentumStarted) { momentumStarted = false; if (MomentumEnded != null) { MomentumEnded.Invoke(eventLayer, this); } } } didGesture = false; }
protected virtual void OnGestureStarted(SKGestureEventArgs e) => GestureStarted?.Invoke(this, e);