Jho*_*hon 9 javascript pinchzoom react-native react-native-gesture-handler
我在捏合手势处理程序内有一个平移手势处理程序,用于创建多方向滚动可缩放视图的效果,该效果一切正常。但我遇到的问题是,当用户放大时,视图不会在手指下放大,而当用户缩放时,视图会放大其他地方,而不是保持相同的位置。这是我的代码:
这是一个可复制的演示:Expo Demo
这是视图:
<PinchGestureHandler
simultaneousHandlers={[panRef]}
ref={pinchRef}
onGestureEvent={pinchGestureHandler}>
<Animated.View style={animatedStyle}>
<PanGestureHandler
simultaneousHandlers={[pinchRef]}
ref={panRef}
onGestureEvent={panGestureHandler}></PanGestureHandler>
</Animated.View>
</PinchGestureHandler>
Run Code Online (Sandbox Code Playgroud)
这是我的处理程序:
const translateX = useSharedValue(0);
const translateY = useSharedValue(0);
const scale = useSharedValue(1);
const panRef = useRef();
const pinchRef = useRef();
const panGestureHandler = useAnimatedGestureHandler({
onStart: (_, ctx) => {
ctx.startX = translateX.value;
ctx.startY = translateY.value;
},
onActive: (event, ctx) => {
translateX.value = ctx.startX + event.translationX;
translateY.value = ctx.startY + event.translationY;
},
onEnd: (event, ctx) => {
translateX.value = withDecay({
velocity: event.velocityX,
deceleration: 0.99,
});
translateY.value = withDecay({
velocity: event.velocityY,
deceleration: 0.99,
});
},
});
const pinchGestureHandler = useAnimatedGestureHandler({
onStart: (_, ctx) => {
ctx.startScale = scale.value;
},
onActive: (event, ctx) => {
scale.value = ctx.startScale * event.scale;
},
onEnd: (event, ctx) => {
scale.value = withSpring(Math.min(Math.max(scale.value, 1), 3));
},
});
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [
{translateX: translateX.value},
{translateY: translateY.value},
{scale: scale.value},
],
};
});
Run Code Online (Sandbox Code Playgroud)
尝试:
尝试调整处理程序以考虑焦点,但缩放仍然远离手指点
const pinchGestureHandler = useAnimatedGestureHandler({
onStart: (_, ctx) => {
ctx.startScale = scale.value;
ctx.startTranslateX = translateX.value;
ctx.startTranslateY = translateY.value;
},
onActive: (event, ctx) => {
scale.value = ctx.startScale * event.scale;
const focalX = event.focalX;
const focalY = event.focalY;
// Adjust translations
translateX.value = ctx.startTranslateX + (1 - event.scale) * (focalX - ctx.startTranslateX);
translateY.value = ctx.startTranslateY + (1 - event.scale) * (focalY - ctx.startTranslateY);
},
onEnd: (_) => {
scale.value = withSpring(Math.min(Math.max(scale.value, 1), 3));
},
});
Run Code Online (Sandbox Code Playgroud)
实际上我认为使用焦点的想法很棒。但我会采取不同的做法。
也许你可以创造两个共享价值观:
const focalX = useSharedValue(0);
const focalY = useSharedValue(0);
Run Code Online (Sandbox Code Playgroud)
然后在紧要关头:
const pinchGestureHandler = useAnimatedGestureHandler({
onActive: (event, ctx) => {
scale.value = event.scale;
focalX.value = event.focalX;
focalY.value = event.focalY;
// No need to adjust translations manually
// translateX.value = ctx.startTranslateX + (1 - event.scale) * (focalX - ctx.startTranslateX);
// translateY.value = ctx.startTranslateY + (1 - event.scale) * (focalY - ctx.startTranslateY);
},
onEnd: (_) => {
scale.value = withSpring(Math.min(Math.max(scale.value, 1), 3));
},
});
Run Code Online (Sandbox Code Playgroud)
在动画风格中你可以尝试:
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [
{ translateX: -focalX.value },
{ translateY: -focalY.value},
{ scale: scale.value },
{ translateY: focalY.value},
{ translateX: focalX.value},
{ translateX: translateX.value },
{ translateY: translateY.value },
],
};
});
Run Code Online (Sandbox Code Playgroud)
基本上在缩放之前,我只是将缩放变换与焦点位置居中。
希望这有效:)
| 归档时间: |
|
| 查看次数: |
656 次 |
| 最近记录: |