React NativeのAnimationについて

react nativeのアニメーションには2つのやり方がある

Animatedを使う場合と、LayoutAnimationがある

Animated

AnimatedはView, Text, Image, ScrollViewの4つのコンポーネントをexportしている

Animated.createAnimatedComponent()を使って独自のコンポーネントを作成することも可能

例:

```
class FadeInView extends React.Component {
  state = {
    fadeAnim: new Animated.Value(0),  // 0で初期化する
  }

  componentDidMount() {
    Animated.timing(                  // 
      this.state.fadeAnim,            // 変化させる値
      {
        toValue: 1,                   // どこまで変化させるか
        duration: 10000,              // どれくらい時間かけるか
      }
    ).start();                        // アニメーション実行
  }

  render() {
    let { fadeAnim } = this.state;

    return (
     
        style={{
          ...this.props.style,
          opacity: fadeAnim,    
        }}
      >
        {this.props.children}
     
    );
  }
}
```


setStateを呼び出して再レンダリングするよりも高速

オプション

Animated.timing
easing: エフェクトの動き
delays 遅延実行 (ミリ秒)


アニメションの順番

アニメーションの同時実行や、直前のアニメーションが終わってから実行させるように設定することも可能

Animated.sequence 順番にアニメーションさせる
Animated.parallel 同時にアニメーションさせる



補完


Animation.Valueの値を別の値で置き換える
例: 0-1の値を0-100に置き換える

value.interpolate({
  inputRange: [0, 1],
  outputRange: [0, 100],
});

必ずしも線形にする必要はない

value.interpolate({
  inputRange: [-300, -100, 0, 100, 101],
  outputRange: [300,    0, 1,   0,   0],
});

Input | Output
------|-------
  -400|    450
  -300|    300
  -200|    150
  -100|      0
   -50|    0.5
     0|      1
    50|    0.5
   100|      0
   101|      0
   200|      0

数字から文字に変換も可能

value.interpolate({
  inputRange: [0, 360],
  outputRange: ['0deg', '360deg']
})



スクロールに合わせて動かす


パラメータ
  state = {
    scrollY: new Animated.Value(0),
  }

Scroll実装

       
          scrollEventThrottle={16}
          onScroll={Animated.event(
            [{ nativeEvent: { contentOffset: { y: scrollY } } }]
          )}
          >

対象のView

       
          style={{
            position: 'absolute',
            top: 30,
            right: 0,
            transform: [{
              translateY: Animated.multiply(scrollY, -1)
            }],
          }}
        >
          Hoge
       

Animated.multiplyは-1で掛け算してる

PanGestureのイベント

onPanResponderMove={Animated.event(
  [null, // ignore the native event
  // extract dx and dy from gestureState
  // like 'pan.x = gestureState.dx, pan.y = gestureState.dy'
  {dx: pan.x, dy: pan.y}
])}

Native Driver


ネイティブ側でアニメーションを実行する
アニメーション中もJSのスレッドがブロックされることはない

ScrrollViewの例

       
          scrollEventThrottle={16}
          onScroll={Animated.event(
            [{ nativeEvent: { contentOffset: { y: scrollY } } }],
            { useNativeDriver: true }
          )}
          >

LayoutAnimation


全てのレイアウト変更に対するアニメーションに便利
flex-boxのレイアウトなど。
ただしできることが少ない

    LayoutAnimation.linear();
    this.setState({ w: this.state.w + 15, h: this.state.h+15 })

0 件のコメント:

コメントを投稿

ReactNativeでAndroid対応する話

前提 ReactNativeでiOS版のアプリをリリースしていて、Android版をリリースする話 トラブルシューティング Build.VERSION_CODES.Q が存在しないエラー compileSdkVersionを29以上にすると解決 メモリー足りないエラー Execu...