LoginSignup
69
48

More than 5 years have passed since last update.

React Nativeでアニメーションさせる基本を理解する

Last updated at Posted at 2016-05-16

React Nativeにおいて現時点でメジャーなAnimationの方法は2つあります。
https://facebook.github.io/react-native/docs/animations.html
AnimatedとLayoutAnimationです。

ezgif.com-resize.gif

Animated

timing, spring, decay

変化させる変数をnew Animated.Valueで定義します。
Animated.springなどに上記変数を渡すことでアニメーションさせられます。

this.state = {
  yellowScale: new Animated.Value(1)
};

// ...

Animated.spring(
  this.state.yellowScale,
  {
    toValue: this._yellowScale - 0.1,
    friction: 1,
   }
).start();
  • Valueの他にValueXYというものもあり、これはtranslateで位置を動かすときに使います。
  • springの他にdecay, timingがある。timingにはeasingが渡せるので最もオーソドックスな方法だと思います。
  • new Animated.Valueで生成されたインスタンスはaddListenerメソッドを通して、変数の変化を取得できる。純増していくとか状態によってアニメーションを変える場合に使えそうです。

Interpolate

new Animated.Valueで生成されたインスタンスはinterpolateメソッドを通して、値を別のレンジに割り当てて出力できます。これは1->100という数字の変化だけじゃなく、colorコードと角度に対応してます。

var color = this.state.backgroundColor.interpolate({
  inputRange: [0, 150, 300],
  outputRange: ['rgba(1, 87, 155, 1.0)', 'rgba(26, 35, 255, 1.0)', 'rgba(38, 50, 56, 1.0)']
});

var deg = this.state.whiteDegree.interpolate({
  inputRange: [0, 1],
  outputRange: ['0deg', '180deg']
});

sequence, parallel, stagger

複数のアニメーションを組み合わせる方法としてsequence,parallel,staggerがあります。
sequenceは順番にparallelは同時にstaggerは一定間隔で実行します。staggerの第一引数は間隔のミリ秒です。

Animated.sequence([
  Animated.parallel([
    Animated.timing(
      this.state.backgroundColor,
        {toValue: 300, duration: 2000}
    ),
    Animated.spring(
      this.state.whiteDegree,
      {toValue: 1, duration: 1500}
    )
  ]),
  Animated.parallel([
    Animated.timing(
      this.state.backgroundColor,
      {toValue: 0, duration: 2000}
    ),
    Animated.spring(
      this.state.whiteDegree,
      {toValue: 0, duration: 1500}
    )
])

LayoutAnimation

Animatedを使わない方法として、LayoutAnimationがあります。
これは次の画面描画サイクルのアニメーションを指定するもので、
例えば、Viewのサイズを広げるstateの変化の前に宣言しとけば、
次の描画サイクルではAnimationが適用されアニメーションしながらViewが広がります。
シンプルなアニメーションしかしない場合には便利かもしれないです。

LayoutAnimation.spring();
this.setState({greenWidth: this.state.greenWidth + 20});

さらにインタラクティブに

ここまでのものを駆使すれば、一方的な動きはある程度表現出来ると思います。
ユーザーの入力に応じてアニメーションさせる際に役立つものとして、PanResponderAnimated.eventがあります。長くなるので詳細は別の機会に残しときます。

サンプル

背景と白い四角はAnimated.sequence, Animated.parallelを使って同時に動かし続けてます。
背景はinterpolateを使って色を変えてます。
startの引数にcallbackを渡すとアニメーション実行後呼ばれるのでローテーションさせられます。

緑の四角はLayoutAnimationを、黄色の四角はAnimateを使って動かしてます。

ezgif.com-resize.gif

コードはこちら
https://gist.github.com/imaimiami/dc90f6315c2964228de8bf3dd3722b3c

以上です。

69
48
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
69
48