美文网首页
react-native-reanimated系列(四)

react-native-reanimated系列(四)

作者: 十豆三撇 | 来源:发表于2021-03-28 21:06 被阅读0次

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

动画

Reanimated提供了许多动画修饰器以及如何自定义动画的方法。

useAnimatedStyle

Shared Value过渡不是启动和运行动画的唯一方法,还可以直接在 useAnimatedStyle中指定动画过渡。

import Animated, { useSharedValue, useAnimatedStyle } from 'react-native-reanimated';

function Box() {
  const offset = useSharedValue(0);

  const animatedStyles = useAnimatedStyle(() => {
    return {
      transform: [
        { 
          translateX: withSpring(offset.value * 255),
        },
      ],
    };
  });

  return (
    <>
      <Animated.View style={[styles.box, animatedStyles]} />
      <Button onPress={() => (offset.value = Math.random())} title="Move" />
    </>
  );
}

中断动画更新

更新Shared Value时,框架不会等待上一个动画完成,而是会立即从上一个动画的当前位置开始进行新的过渡。
如果想要在上一个动画完成后再开始下一个动画,可以使用上一个动画完成的回调来进行操作。
如果想要在开始一个新动画之前取消当前正在运行的动画,可以使用cancelAnimation方法。

自定义动画

Reanimated目前有三个动画辅助方法:withTimingwithSpringwithDecay

<Button
  onPress={() => {
    offset.value = withSpring(Math.random(), {}, (finished) => {
      if (finished) {
        console.log("ANIMATION ENDED");
      } else {
        console.log("ANIMATION GOT CANCELLED");
      }
    });
  }}
  title="Move"
/>

Timing

Reanimated包提供了Easing.bezier方法,因此可以使用贝塞尔曲线来描述缓动。通常使用Easing.inEasing.outEasing.inOut分别在起点,终点或两端调整时序曲线就足够了。Timing动画的默认持续时间为300毫秒,默认缓动为in-Out二次曲线(Easing.inOut(Easing.quad))。

easeInOutQuad.png
import { Easing, withTiming } from 'react-native-reanimated';

offset.value = withTiming(0, {
  duration: 500,
  easing: Easing.out(Easing.exp),
});

Spring

与Timing动画不同,Spring动画不将持续时间作为参数,而是由spring物理特性、初始速度和行进距离决定。

import Animated, {
  withSpring,
  useAnimatedStyle,
  useSharedValue,
} from 'react-native-reanimated';

function Box() {
  const offset = useSharedValue(0);

  const defaultSpringStyles = useAnimatedStyle(() => {
    return {
      transform: [{ translateX: withSpring(offset.value * 255) }],
    };
  });

  const customSpringStyles = useAnimatedStyle(() => {
    return {
      transform: [
        {
          translateX: withSpring(offset.value * 255, {
            damping: 20,
            stiffness: 90,
          }),
        },
      ],
    };
  });

  return (
    <>
      <Animated.View style={[styles.box, defaultSpringStyles]} />
      <Animated.View style={[styles.box, customSpringStyles]} />
      <Button onPress={() => (offset.value = Math.random())} title="Move" />
    </>
  );
}
twosprings.gif

动画修饰器

Reanimated目前有三个修饰器:withDelaywithSequencewithRepeat

  • withDelay修饰的动画以给定的延迟开始
  • withSequence修饰的动画依次开始运行
  • withRepeat修饰的动画重复运行几次
import Animated, { useSharedValue, useAnimatedStyle } from 'react-native-reanimated';

function WobbleExample(props) {
  const rotation = useSharedValue(0);

  const animatedStyle = useAnimatedStyle(() => {
    return {
      transform: [{ rotateZ: `${rotation.value}deg` }],
    };
  });

  return (
    <>
      <Animated.View style={[styles.box, animatedStyle]} />
      <Button
        title="wobble"
        onPress={() => {
          rotation.value = withRepeat(withTiming(10), 6, true)
        }}
      />
    </>
  );
}

上面代码中,第一个参数表示目标角度10,第二个参数表示重复6次,第三个参数反转标志为true表示动画每隔一个重复反向运行。

swing.gif
上面的代码使视图旋转仅在0到10度之间进行。 为了使视图也向左摆动,可以从-10开始并转到10度。 但是我们不能仅将初始值更改为-10,因为在这种情况下,矩形将从一开始就倾斜。 解决此问题的一种方法是使用withSequence修饰符,并从0开始,将第一个动画执行到-10,然后将视图从-10摆动到10几次,最后从-10变为0。
rotation.value = withSequence(
  withTiming(-10, { duration: 50 }),
  withRepeat(withTiming(10, { duration: 100 }), 6, true),
  withTiming(0, { duration: 50 })
);
wobble.gif

相关文章

网友评论

      本文标题:react-native-reanimated系列(四)

      本文链接:https://www.haomeiwen.com/subject/hohphltx.html