UNPKG

@100mslive/react-native-room-kit

Version:

100ms Room Kit provides simple & easy to use UI components to build Live Streaming & Video Conferencing experiences in your apps.

122 lines (121 loc) 4 kB
import * as React from 'react'; import { GestureDetector, Gesture } from 'react-native-gesture-handler'; import Animated, { useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated'; export const HMSPinchGesture = ({ children, style }) => { /** * - Dimensions of Animated View * This will be used to apply transformations as per width and height of Animated Views */ const dimensions = useSharedValue({ width: 0, height: 0 }); /** * - focal point captured at the start of the pinch gesture * We use this point to calculate the amount of translation of focal point * ` * translation = (current focal point) - (focal point at the start of the gesture) * ` * then translation value is amount of swipe(pan) gesture user has applied while scaling * we can use this calculated value as a translation value, similar to what we get in `pan gesture` */ const focalPointAtStart = useSharedValue({ x: 0, y: 0 }); const scale = useSharedValue(1); const savedScale = useSharedValue(1); const translation = useSharedValue({ x: 0, y: 0 }); const savedTranslation = useSharedValue({ x: 0, y: 0 }); const handleLayoutChange = React.useCallback(({ nativeEvent }) => { dimensions.value = { width: nativeEvent.layout.width, height: nativeEvent.layout.height }; }, []); const panGesture = Gesture.Pan().maxPointers(1).onUpdate(e => { if (savedScale.value <= 1) { return; } const swipeOnXAxis = e.translationX + savedTranslation.value.x; const swipeOnYAxis = e.translationY + savedTranslation.value.y; const diffX = (dimensions.value.width * savedScale.value - dimensions.value.width) / 2; const diffY = (dimensions.value.height * savedScale.value - dimensions.value.height) / 2; translation.value = { x: Math.max(Math.min(swipeOnXAxis, diffX), -diffX), y: Math.max(Math.min(swipeOnYAxis, diffY), -diffY) }; }).onEnd(() => { savedTranslation.value = translation.value; }); const pinchGesture = Gesture.Pinch().onStart(e => { focalPointAtStart.value = { x: e.focalX, y: e.focalY }; }).onUpdate(e => { scale.value = Math.min(Math.max(savedScale.value * e.scale, 0.94), 5.2); const offsetX = dimensions.value.width / 2 - focalPointAtStart.value.x; const offsetY = dimensions.value.height / 2 - focalPointAtStart.value.y; const swipeOnXAxis = offsetX * scale.value + savedTranslation.value.x; const swipeOnYAxis = offsetY * scale.value + savedTranslation.value.y; const diffX = (dimensions.value.width * scale.value - dimensions.value.width) / 2; const diffY = (dimensions.value.height * scale.value - dimensions.value.height) / 2; translation.value = { x: Math.max(Math.min(swipeOnXAxis, diffX), -diffX), y: Math.max(Math.min(swipeOnYAxis, diffY), -diffY) }; }).onEnd(() => { if (scale.value < 1) { scale.value = withSpring(1, { damping: 100, stiffness: 200 }); savedScale.value = 1; translation.value = { x: 0, y: 0 }; } else if (scale.value > 5) { scale.value = withSpring(5, { damping: 100, stiffness: 200 }); savedScale.value = 5; } else { savedScale.value = scale.value; } savedTranslation.value = translation.value; }); const animatedStyle = useAnimatedStyle(() => ({ transform: [{ translateX: translation.value.x }, { translateY: translation.value.y }, { scale: scale.value }] })); return /*#__PURE__*/React.createElement(GestureDetector, { gesture: Gesture.Exclusive(panGesture, pinchGesture) }, /*#__PURE__*/React.createElement(Animated.View, { style: { flex: 1 } }, /*#__PURE__*/React.createElement(Animated.View, { onLayout: handleLayoutChange, style: [style, animatedStyle] }, children))); }; //# sourceMappingURL=HMSPinchGesture.js.map