我正在使用react-native-reanimated和 react-native-gesture-handler创建一个允许您“探索”其内部内容的 View (即使它超出其宽度和高度)。
这是我的 gestureHandler
更新translationX
& translationY
变量,稍后在 useAnimatedStyle
中使用“移动”<Animated.View>
:
const gestureHandler = useAnimatedGestureHandler({
onStart: (_, ctx) => {
ctx.startX = translationX.value;
ctx.startY = translationY.value;
},
onActive: (event, ctx) => {
'worklet';
translationX.value = ctx.startX + event.translationX;
translationY.value = ctx.startY + event.translationY;
// update state to view values on the screen as they change
runOnJS(setPosition)({ x: translationX.value, y: translationY.value });
},
onEnd: () => {
'worklet';
const boundedX = clamp(
translationX.value,
(BOX_WIDTH - container?.width) * -1,
0
);
const boundedY = clamp(
translationY.value,
(BOX_HEIGHT - container?.height) * -1,
0
);
// create "bounce-y" effect when moving the box back inside the bounds
translationX.value = withTiming(boundedX);
translationY.value = withTiming(boundedY);
// update state to view values on the screen as they change
runOnJS(setPosition)({ x: boundedX, y: boundedY });
},
});
此代码在以下情况下“有效”:
- 我的“可见区域”为
width: 100, height: 100
width: 160, height: 160
的“box”(正在平移的元素)
这是一个 gif (click to view in full size):
我创建了一个示例 Expo Snack显示我的问题。如果你改变INITIAL_SCALE
在Transforms.js
至0.5
或者只需点击粉色框(它将其比例更改为 NEW_SCALE
,请参阅 onPress()
),边界平移不再有效。
最佳答案
我发现了问题,它是使用原点(中心)缩放框,因此在应用 scale
变换之前,我必须将其转换为“假”,将其原点设置为顶部左角。
{ translateX: -BOX_WIDTH / 2 },
{ translateY: -BOX_HEIGHT / 2 },
{ scale: scale.value }, // <- NOW I am changing the scale of the box
{ translateX: BOX_WIDTH / 2 },
{ translateY: BOX_HEIGHT / 2},
我还创建了一个函数来计算外框的“边缘”,并考虑到粉红色框的比例:
const getEdges = () => {
'worklet';
const pointX =
(BOX_WIDTH * scale.value - VISIBLE_AREA_WIDTH) * -1;
const pointY =
(BOX_HEIGHT * scale.value - VISIBLE_AREA_HEIGHT) * -1;
return {
x: {
min: Math.min(pointX, 0),
max: Math.max(0, pointX),
},
y: {
min: Math.min(pointY, 0),
max: Math.max(0, pointY),
},
};
};
这是一个working Snack通过这些修复。
有用信息:
关于react-native - 缩放后在父 View 的边界内平移 Animated.View,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70768948/