react-native-reanimated系列(五)

2021-03-29  本文已影响0人  十豆三撇

react-native-reanimated系列(一)
react-native-reanimated系列(二)
react-native-reanimated系列(三)
react-native-reanimated系列(四)

事件

为了使APP对用户体验更自然,我们使用动画来平滑用户与APP用户界面的交互。

处理手势事件

const EventsExample = () => {
  const pressed = useSharedValue(false);
  const eventHandler = useAnimatedGestureHandler({
    onStart: (event, ctx) => {
      pressed.value = true;
    },
    onEnd: (event, ctx) => {
      pressed.value = false;
    },
  });
  const uas = useAnimatedStyle(() => {
    return {
      backgroundColor: pressed.value ? '#FEEF86' : '#001972',
      transform: [{ scale: withSpring(pressed.value ? 1.2 : 1) }],
    };
  });
  return (
    <TapGestureHandler onGestureEvent={eventHandler}>
      <Animated.View style={[styles.ball, uas]} />
    </TapGestureHandler>
  );
};
touch-final.gif

处理连续手势

const EventsExample = () => {
  const startingPosition = 100;
  const x = useSharedValue(startingPosition);
  const y = useSharedValue(startingPosition);
  const pressed = useSharedValue(false);
  const eventHandler = useAnimatedGestureHandler({
    onStart: (event, ctx) => {
      pressed.value = true;
      ctx.startX = x.value;
      ctx.startY = y.value;
    },
    onActive: (event, ctx) => {
      x.value = ctx.startX + event.translationX;
      y.value = ctx.startY + event.translationY;
    },
    onEnd: (event, ctx) => {
      pressed.value = false;
      x.value = withSpring(startingPosition);
      y.value = withSpring(startingPosition);
    },
  });
  const uas = useAnimatedStyle(() => {
    return {
      backgroundColor: pressed.value ? '#FEEF86' : '#001972',
      transform: [{ translateX: x.value }, { translateY: y.value }],
    };
  });
  return (
    <PanGestureHandler onGestureEvent={eventHandler}>
      <Animated.View style={[styles.ball, uas]} />
    </PanGestureHandler>
  );
};

当启动新手势时,事件中携带的转换值是相对于手势的开始位置而言的。结果,我们不能直接将手势转换映射到屏幕上的视图偏移。解决方案是设置一个可以保持视图起始偏移量的临时状态。为此,我们可以使用提供给每个手势处理程序worklets的上下文参数。上下文只是在所有回调之间共享的JavaScript对象。换句话说,所有定义为手势处理程序回调的方法都将接收相同的上下文对象实例。


final.gif

迁移

常见问题解决方案

TypeError: Cannot convert undefined value to object on someVariable._closure

清除metro缓存,确保安装了babel插件

watchman watch-del-all
yarn start --reset-cache

undefined is not an object (evaluating '_toConsumableArray(Array(length)).map')

worklet不支持扩展运算符(...array),可以使用以下方法替代:

上一篇 下一篇

猜你喜欢

热点阅读