@openspacelabs/react-native-zoomable-view
Version:
A view component for react-native with pinch to zoom, tap to move and double tap to zoom capability.
53 lines (46 loc) • 1.72 kB
text/typescript
import { GestureResponderEvent, PanResponderGestureState } from 'react-native';
import { Vec2D } from '../typings';
export { calcNewScaledOffsetForZoomCentering } from './calcNewScaledOffsetForZoomCentering';
/**
* Calculates the gesture center point relative to the page coordinate system
*
* We're unable to use touch.locationX/Y
* because locationX uses the axis system of the leaf element that the touch occurs on,
* which makes it even more complicated to translate into our container's axis system.
*
* We're also unable to use gestureState.moveX/Y
* because gestureState.moveX/Y is messed up on real device
* (Sometimes it's the center point, but sometimes it randomly takes the position of one of the touches)
*/
export function calcGestureCenterPoint(
e: GestureResponderEvent,
gestureState: PanResponderGestureState
): Vec2D | null {
const touches = e.nativeEvent.touches;
if (!touches[0]) return null;
if (gestureState.numberActiveTouches === 2) {
if (!touches[1]) return null;
return {
x: (touches[0].pageX + touches[1].pageX) / 2,
y: (touches[0].pageY + touches[1].pageY) / 2,
};
}
if (gestureState.numberActiveTouches === 1) {
return {
x: touches[0].pageX,
y: touches[0].pageY,
};
}
return null;
}
export function calcGestureTouchDistance(
e: GestureResponderEvent,
gestureState: PanResponderGestureState
): number | null {
const touches = e.nativeEvent.touches;
if (gestureState.numberActiveTouches !== 2 || !touches[0] || !touches[1])
return null;
const dx = Math.abs(touches[0].pageX - touches[1].pageX);
const dy = Math.abs(touches[0].pageY - touches[1].pageY);
return Math.sqrt(dx * dx + dy * dy);
}