PUROGU LADESU

ポエムがメインのブログです。

【ReactNative】Animationを使う

基本

Animations · React Native

AnimatedとLayoutAnimationという2つのAPIが用意されている。

Animated

動作をいろいろ指定してプログラムします。

  • Animated.Viewなどで描画する
    Animated.Image
    Animated.ScrollView
    Animated.Text
    Animated.View
    Animated.FlatList
    Animated.SectionList

  • Animated.Valueなどで変化させる値を定義する
    Animated.Value() 単一の値
    Animated.ValueXY() 2Dのクラス用

  • interpolateで値を変換する(任意)

  • Animated.timingなどで値を変化させる
    Animated.decay 減衰する
    Animated.spring 跳ねる
    Animated.timing Easingなどを使って変化させる

Easing

値を変化させる速さを調整することでエフェクトを調整する
Easing · React Native

アルゴリズムのサンプル
Easing Functions Cheat Sheet

LayoutAnimation

多分次の状態への変化をいい感じにアニメーションしてくれるようなものだと思う。 細かな設定をするのではなくライブラリに任せてざっくりやってもらう感じ? 意外と実用的なんじゃないかと思う。

LayoutAnimation · React Native

巨大化させる

let sizev = new Animated.Value(50);

const animate = () => {
    sizev.setValue(50);
    Animated.timing(sizev, {
      toValue: 100,
      duration: 1000,
      easing: Easing.out(Easing.back()),
    }).start();
  };

 const animatedStyle = [
    {
      backgroundColor: "gold",
      height: sizev,
      width: sizev,
      borderRadius: 10,
    },
  ];

return <Animated.View style={animatedStyle}></Animated.View>

回転させる

const degAnim = useRef(new Animated.Value(0)).current;

const kurukuru = () => {
    degAnim.setValue(0);
    Animated.loop(
      Animated.sequence([
        Animated.spring(degAnim, { toValue: 1 }),
        Animated.spring(degAnim, { toValue: 0 }),
      ])
    ).start();
  };

const degNum = degAnim.interpolate({
    inputRange: [0, 1],
    outputRange: ["0deg", "60deg"],
  });

const animatedStyle = [
    {
      backgroundColor: "tomato",
      height: sizev,
      width: sizev,
      borderRadius: 10,
      transform: [{ rotate: degNum }],
    },
  ];

return <Animated.View style={animatedStyle}></Animated.View>

サイズを変える(LayoutAnimation)

const Lbox = () => {
  const [size, setSize] = React.useState(80);

  const action = () => {
    // 状態変更前にアニメーションを定義する
    LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);

    if (size < 100) {
      setSize(120);
    } else {
      setSize(80);
    }
  };

  const boxStyle = [
    {
      backgroundColor: "tomato",
      height: size,
      width: size,
      borderRadius: 10,
      margin: 10,
    },
  ];

  return (
    <TouchableOpacity style={boxStyle} onPress={action}></TouchableOpacity>
  );
};

タッチやジェスチャーを組み合わせてアニメーションする場合

ドラッグで動かしたりする場合はPanResponderを使うようです。 これは別途学習が必要そうです。

PanResponder · React Native