Animatedを使ったアニメーションの中で、バネのように跳ねるようなアニメーションをするAnimated.spring()という面白いメソッドがあったので、この使い方を紹介する。

以前作ったサンプルアプリのコードを改変しながら実装していくので、以下の記事をまずは参照してほしい。

https://chusotsu-program.com/react-native-animated-loop

今回はニュース記事の読み込みが終わったら、記事リスト表示時にテキストを伸び縮みさせるアニメーションを実装する。

TextをAnimated.Textに置き換える

テキストに対しアニメーションを適用させるので、まずはTextをAnimated.Textに置き換える。

<Animated.Text>
  {item.data.title}
</Animated.Text>

state変数の定義

次にコンストラクタ内でフォントサイズを管理するstate変数を定義する。

constructor() {
  super();
  this.state = {
    isLoading: true,
    threads: [],
    opacity: new Animated.Value(0),
    fontSize: new Animated.Value(0),
  }
}

Animated.spring()を実装

animate()メソッド内にAnimated.spring()の処理を書いていく。

animate() {
  Animated.timing(this.state.opacity, {
    toValue: 1,
    duration: 1000,
  }).start();

  Animated.spring(this.state.fontSize, {
    toValue: 1,
    friction: 1,
  }).start();
}

frictionに設定する値はここでは1としているが、0.1など小さい値を設定するとより大きく跳ねるアニメーションとなる。

renderメソッドの変更

最後にrenderメソッド内のコードを以下のとおり書き換える。

render() {
  const { threads, isLoading, opacity, fontSize } = this.state;
  const { width } = Dimensions.get('window');
  const _fontSize = fontSize.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 12]
  })

  if(!isLoading)
    this.animate();

  return(
    <View style={{
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
    }}>
      {isLoading ? <Spining /> :
        <Animated.View style={{ opacity: opacity}}>
        <FlatList
          data={threads}
          renderItem={({item}) => {
            return(
              <View style={{
                flex: 1,
                flexDirection: 'row',
                width: '100%'
              }}>
                <Image
                  style={{
                    width: 50,
                    height: 50
                  }}
                  source={item.data.thumbnail}
                />
                  <View style={{
                    flex: 1,
                    flexDirection: 'column'
                  }}>
                    <Animated.Text style={{fontSize: _fontSize}}>{item.data.title}</Animated.Text>
                    <Text style={{color: '#ababab', fontSize: 10}}>{item.data.domain}</Text>
                  </View>
              </View>
            )
          }}
        />
        </Animated.View>
      }
    </View>
  )
}

4行目でinterpolateを使用し、フォントサイズをアニメーション用に変換させているところがポイントだ。

この処理を行うことで、アニメーション開始時はフォントサイズが0、終了時に12となる。

アニメーションの確認

それではexpo startコマンドを実行し、出来上がったアニメーションを確認してみよう。

記事リストが読み込まれると、テキストが跳ねるようなアニメーションが実行される。