react-native-zoomable-view
Version:
Zoomable View or Image on React Native with reanimated v2
108 lines • 3.13 kB
JavaScript
import React from 'react';
import { StyleSheet, useWindowDimensions } from 'react-native';
import { PanGestureHandler, PinchGestureHandler, RotationGestureHandler } from 'react-native-gesture-handler';
import Animated, { useAnimatedGestureHandler, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';
const styles = StyleSheet.create({
container: {
alignItems: 'center',
justifyContent: 'center'
},
focalPoint: { ...StyleSheet.absoluteFillObject,
width: 20,
height: 20,
backgroundColor: 'blue',
borderRadius: 10
}
});
export const ZoomableView = ({
children
}) => {
const scale = useSharedValue(1);
const rotate = useSharedValue(0);
const focalX = useSharedValue(0);
const focalY = useSharedValue(0);
const transitionX = useSharedValue(0);
const transitionY = useSharedValue(0);
const {
width
} = useWindowDimensions();
const imagePinch = /*#__PURE__*/React.createRef();
const imageRotation = /*#__PURE__*/React.createRef();
const imagePan = /*#__PURE__*/React.createRef();
const pinchHandler = useAnimatedGestureHandler({
onActive: event => {
scale.value = event.scale;
focalX.value = event.focalX;
focalY.value = event.focalY;
},
onEnd: () => {
scale.value = 1;
}
});
const roteteHandler = useAnimatedGestureHandler({
onActive: event => {
rotate.value = event.rotation * 90;
},
onEnd: () => {
rotate.value = withSpring(0);
}
});
const panHandler = useAnimatedGestureHandler({
onActive: event => {
transitionX.value = -event.translationX;
transitionY.value = -event.translationY;
},
onEnd: () => {
transitionX.value = withSpring(0);
transitionY.value = withSpring(0);
}
});
const rStyle = useAnimatedStyle(() => ({
transform: [{
translateX: focalX.value
}, {
translateY: focalY.value
}, {
translateX: -100
}, {
translateY: -100
}, {
scale: scale.value
}, {
translateX: -focalX.value
}, {
translateY: -focalY.value
}, {
translateX: 100
}, {
translateY: 100
}, {
rotate: `${rotate.value}deg`
}, {
translateX: -transitionX.value
}, {
translateY: -transitionY.value
}]
}));
return /*#__PURE__*/React.createElement(PanGestureHandler, {
simultaneousHandlers: [imagePinch, imageRotation],
onGestureEvent: panHandler,
ref: imagePan
}, /*#__PURE__*/React.createElement(Animated.View, null, /*#__PURE__*/React.createElement(PinchGestureHandler, {
ref: imagePinch,
simultaneousHandlers: [imagePan, imageRotation],
onGestureEvent: pinchHandler
}, /*#__PURE__*/React.createElement(Animated.View, {
style: {
width
}
}, /*#__PURE__*/React.createElement(RotationGestureHandler, {
ref: imageRotation,
simultaneousHandlers: [imagePan, imagePinch],
onGestureEvent: roteteHandler
}, /*#__PURE__*/React.createElement(Animated.View, {
style: [styles.container, rStyle],
collapsable: false
}, children))))));
};
//# sourceMappingURL=ZoomableView.js.map