react-native-reanimated系列(五)

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

迁移

  • interpolate重命名interplolateNode
    如果您使用的是类成员方法AnimatedValue.interpolate,则无需更改。
  • Easing重命名EasingNode

常见问题解决方案

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),可以使用以下方法替代:

  • 拷贝数组array.slice()
  • [...Array(length)].map的惯用语法Array(length).fill().map()
  • 合并对象Object.assign()
  • 函数里传递参数func.apply()
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    余生动听阅读 10,926评论 0 11
  • 彩排完,天已黑
    刘凯书法阅读 4,506评论 1 3
  • 没事就多看看书,因为腹有诗书气自华,读书万卷始通神。没事就多出去旅游,别因为没钱而找借口,因为只要你省吃俭用,来...
    向阳之心阅读 4,988评论 3 11
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 130,048评论 2 7

友情链接更多精彩内容