react-native-reanimated系列(四)

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時,框架不會等待上一個動畫完成,而是會立即從上一個動畫的當(dāng)前位置開始進行新的過渡。
如果想要在上一個動畫完成后再開始下一個動畫,可以使用上一個動畫完成的回調(diào)來進行操作。
如果想要在開始一個新動畫之前取消當(dāng)前正在運行的動畫,可以使用cancelAnimation方法。

自定義動畫

Reanimated目前有三個動畫輔助方法:withTiming、withSpringwithDecay。

<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.in,Easing.outEasing.inOut分別在起點,終點或兩端調(diào)整時序曲線就足夠了。Timing動畫的默認持續(xù)時間為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動畫不將持續(xù)時間作為參數(shù),而是由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目前有三個修飾器:withDelay、withSequencewithRepeat

  • withDelay修飾的動畫以給定的延遲開始
  • withSequence修飾的動畫依次開始運行
  • withRepeat修飾的動畫重復(fù)運行幾次
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)
        }}
      />
    </>
  );
}

上面代碼中,第一個參數(shù)表示目標角度10,第二個參數(shù)表示重復(fù)6次,第三個參數(shù)反轉(zhuǎn)標志為true表示動畫每隔一個重復(fù)反向運行。

swing.gif

上面的代碼使視圖旋轉(zhuǎn)僅在0到10度之間進行。 為了使視圖也向左擺動,可以從-10開始并轉(zhuǎn)到10度。 但是我們不能僅將初始值更改為-10,因為在這種情況下,矩形將從一開始就傾斜。 解決此問題的一種方法是使用withSequence修飾符,并從0開始,將第一個動畫執(zhí)行到-10,然后將視圖從-10擺動到10幾次,最后從-10變?yōu)?。

rotation.value = withSequence(
  withTiming(-10, { duration: 50 }),
  withRepeat(withTiming(10, { duration: 100 }), 6, true),
  withTiming(0, { duration: 50 })
);
wobble.gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容