我在捏合手势处理器内部放置了一个平移手势处理器,以创建多方向滚动缩放视图的效果,一切都运行良好。但是我遇到了一个问题,当用户放大时,视图并没有在他们的手指下放大,而是在其他地方放大,位置没有保持不变。以下是我的代码:
这是一个可复现的演示:Expo Demo 这是视图:
这是我的处理程序:
尝试调整处理程序以考虑焦点,但缩放仍然与手指的位置相差甚远。
这是一个可复现的演示:Expo Demo 这是视图:
<PinchGestureHandler
simultaneousHandlers={[panRef]}
ref={pinchRef}
onGestureEvent={pinchGestureHandler}>
<Animated.View style={animatedStyle}>
<PanGestureHandler
simultaneousHandlers={[pinchRef]}
ref={panRef}
onGestureEvent={panGestureHandler}></PanGestureHandler>
</Animated.View>
</PinchGestureHandler>
这是我的处理程序:
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},
],
};
});
尝试调整处理程序以考虑焦点,但缩放仍然与手指的位置相差甚远。
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));
},
});