react-native - 缩放后在父 View 的边界内平移 Animated.View

标签 react-native react-native-gesture-handler react-native-reanimated-v2

我正在使用react-native-reanimatedreact-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_SCALETransforms.js0.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/

相关文章:

android - 如何使用 react native 集市显示来电

react-native - react 原生中从右到左

javascript - 您为我们提供了节点类型 TSInstantiationExpression 的访问者,但它不是有效类型

typescript - useAnimatedGestureHandler onStart 方法正确的上下文参数类型

javascript - PanGestureHandler 预期 `onGestureHandlerEvent` 监听器是一个函数

reactjs - Reanimated 2 Hook 中依赖参数的更好用例是什么?

react-native - TypeError : _ReanimatedModule. default.configureProps 不是函数

Android react-native-push-notification onNotification 当应用程序在后台并单击通知时未调用?

android - 任务 ':app:preDebugBuild' react 失败,执行 native android

ios - React Native Swipeable(滑动删除)未关闭