You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合react-native-gesture-handler与Reanimated实现矩阵变换衰减效果?

问题:React Native新版Gestures API中结合矩阵变换与withDecay衰减效果

我正在学习react-native-gesture-handler和react-native-reanimated,想用矩阵实现变换,但不知道怎么结合withDecay这类物理动画函数。我要使用新版Gestures API,不想用旧版gestureHandler API。参考了一个通过矩阵相乘实现变换的示例,效果不错,但想加平移结束后的衰减滑动效果。尝试在.onEnd事件里实现,但代码跑不起来,我的尝试代码如下:

const pan = Gesture.Pan()
  .onChange(e => {
    matrix.value = multiply4(
      Matrix4.translate(e.changeX, e.changeY, 0),
      matrix.value,
    );
  })
  .onEnd(({velocityX, velocityY}) => {
    matrix.value = multiply4(
      Matrix4.translate(
        withDecay({velocity: velocityX}),
        withDecay({velocity: velocityY}),
        0,
      ),
      matrix.value,
    );
  });

解决方案

你代码失效的核心原因:withDecay返回的是动画驱动的动态值,而Matrix4.translate需要传入静态数值,直接混用会导致动画无法正确触发。以下提供两种可行的实现方式:

方式一:保留矩阵直接操作(适合复杂多变换场景)

通过监听衰减动画的每一帧增量,实时更新变换矩阵:

import { Gesture } from 'react-native-gesture-handler';
import { useSharedValue, withDecay, multiply4, Matrix4, runOnUI, useAnimatedReaction } from 'react-native-reanimated';

// 初始化变换矩阵
const matrix = useSharedValue(Matrix4.identity());
// 存储衰减过程中每帧的偏移增量
const tempDecayX = useSharedValue(0);
const tempDecayY = useSharedValue(0);

// 监听增量变化,更新矩阵
useAnimatedReaction(
  () => [tempDecayX.value, tempDecayY.value],
  ([dx, dy]) => {
    if (dx !== 0 || dy !== 0) {
      matrix.value = multiply4(Matrix4.translate(dx, dy, 0), matrix.value);
      // 重置增量,避免重复累加
      tempDecayX.value = 0;
      tempDecayY.value = 0;
    }
  },
  [matrix]
);

const pan = Gesture.Pan()
  .onChange((e) => {
    // 手势拖动时直接更新矩阵
    matrix.value = multiply4(Matrix4.translate(e.changeX, e.changeY, 0), matrix.value);
  })
  .onEnd(({ velocityX, velocityY }) => {
    runOnUI(() => {
      // X轴衰减:计算每帧偏移增量并触发矩阵更新
      tempDecayX.value = withDecay({
        velocity: velocityX,
        onUpdate: (currentValue) => {
          tempDecayX.value = currentValue - tempDecayX.value;
        },
      });
      // Y轴衰减同理
      tempDecayY.value = withDecay({
        velocity: velocityY,
        onUpdate: (currentValue) => {
          tempDecayY.value = currentValue - tempDecayY.value;
        },
      });
    })();
  });

方式二:拆分平移值(适合仅平移或简单变换场景)

将平移分量从矩阵中拆分出来,直接用withDecay驱动平移值,再组合成矩阵,代码更简洁:

import { Gesture } from 'react-native-gesture-handler';
import { useSharedValue, withDecay, Matrix4, useAnimatedStyle } from 'react-native-reanimated';

const translateX = useSharedValue(0);
const translateY = useSharedValue(0);

// 根据平移值生成变换矩阵
const animatedStyle = useAnimatedStyle(() => {
  const transformMatrix = Matrix4.translate(translateX.value, translateY.value, 0);
  // 如需叠加缩放、旋转等,可在此处组合多个矩阵
  return { transform: [{ matrix: transformMatrix }] };
});

const pan = Gesture.Pan()
  .onChange((e) => {
    translateX.value += e.changeX;
    translateY.value += e.changeY;
  })
  .onEnd(({ velocityX, velocityY }) => {
    // 直接用withDecay驱动平移值的衰减动画
    translateX.value = withDecay({ velocity: velocityX });
    translateY.value = withDecay({ velocity: velocityY });
  });

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 14:45:33