React NativeにLottieアニメーションを実装したときに苦労した3つのこと

この記事は[React Native Advent Calendar 2019](https://qiita.com/advent-calendar/2019/react-native)の18日目の記事です。

![liquid_text_animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186009/ec0affb8-5dc3-3cd6-89c3-033b3e910ca6.gif)

## はじめに
こんにちは、React Nativeでアプリ開発をしている @tamago3keran です。
私が所属する会社で開発しているアプリに、Lottieというライブラリを使って、アニメーションを実装していたりします。

Lottieの良さを紹介したり、導入方法を紹介する記事はよく見かけるので、今回はLottieを使ってアニメーションを実装したときに苦労したことを書こうと思います！

## 想定読者
- Lottieの仕組みがわかっている人（ Lottieについて知りたい方は[こちら](https://note.com/marina1017/n/na3986d57cd37)をご参考ください ）
- React NativeアプリにLottieを使ってアニメーションを実装しようとしている人
- React NativeアプリにLottieを使ってアニメーションを実装する際の注意点を知りたい人


## Lottieとは
![Introduction_00_sm.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186009/e88bdf8a-a899-533c-c0fb-d8c4705e319e.gif)

LottieとはAirbnb社が開発するアニメーション表示ライブラリです。After Effectsで作成されたアニメーションをBodymovinを使ってJSONファイルに変換し、そのJSONファイルを元にアニメーションをレンダリングします。

iOSやAndroid、React Native、Flutterなど幅広いプラットフォームで利用することができます。詳しくは、Lottieの[公式サイト](https://airbnb.design/lottie/)をご覧ください！

## Lottieアニメーション実装時に苦労したこと
Lottieを使えば、アニメーションのために複雑なコードを書かずに済みます。またGIF画像とは違い、JSONファイルを使用してアニメーションをレンダリングするので、アプリサイズも抑えることができます。

Lottieを使うメリットは他にもありますが、一方で苦労したこともあります。今回は私の経験を元に、Lottieを使ったアニメーション実装で苦労したことを3つ紹介しようと思います！


### 不具合が起きたらlottie-react-native以外のリポジトリも調査する必要がある
React NativeにLottieを導入するときは、[lottie-react-native](https://github.com/react-native-community/lottie-react-native)というライブラリを使用します。README通りにインストールするのですが、導入当時はしばしばエラーが発生していました。

中でも印象に残っているのは、Androidでアニメーションを表示するときにだけ、クラッシュしてしまうというエラーです。lottie-react-nativeのGitHubリポジトリではなく、lottie-androidの方に[Issue](https://github.com/airbnb/lottie-android/issues/1177#issuecomment-481635211)が上がっていたからです。

**lottie-react-nativeでエラーが起きたら...**
lottie-react-nativeを使用してエラーが起きた場合は、[lottie-ios](https://github.com/airbnb/lottie-ios)や[lottie-android](https://github.com/airbnb/lottie-android)のリポジトリも調査することをおすすめします。

実はlottie-react-nativeは内部でlottie-iosやlottie-androidの機能を使って、アニメーションを表示しているのです。だから、lottie-iosやlottie-androidの方にIssueが上がることがあります。

![20190706233700.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186009/e5224acd-f807-9ad4-4ab9-bdd10f76cc4b.png)

lottie-react-nativeの内部で使用されているlottie-iosやlottie-androidのバージョンが気になる方は、以下のファイルをご確認ください！

- lottie-ios: https://github.com/react-native-community/lottie-react-native/blob/master/package.json#L50
- lottie-android: https://github.com/react-native-community/lottie-react-native/blob/master/build.gradle#L9

### サポートしていないAfter Effectsの機能がある
After Effectsで作成したアニメーションが、端末上だと作成した通りに表示されないことがありました。導入当初は理由がわからず、困惑しました。

実は、LottieはAfter Effectsの全ての機能に対応しているわけではありません。また、iOSとAndroidでサポートしている機能に差分があります。

<img width="824" alt="Screen Shot 2019-12-17 at 7.22.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186009/1d2ab14a-c703-3dcb-d744-3939c9959076.png">

引用元: https://airbnb.io/lottie/#/supported-features

さらに、Supported Featuresがまとめられているページにも、lottie-iosやlottie-androidの各バージョンが、どの機能をサポートしているかは明記されていません。

**正常にレンダリングされるアニメーションを効率よく作るには...**
Supported Featuresを参考にしつつ、端末でこまめに表示確認をしながら、アニメーションを作成することをおすすめします。

作り込んだあとにアニメーションを変更するより、端末上で少しずつ確認しながら作ったほうが、手戻りが少なくて済みます。

### 表示速度がAfter Effectsと端末で異なる
ローディングのアニメーションを作成していたときに、After Effects上の再生速度よりも端末の再生速度が若干遅いことに気づきました。

ローディングのアニメーションの再生速度が遅いと、ユーザに対してローディングが遅いという印象を与えかねません。デザイナーと相談しながら、再生速度を調整しなければなりませんでした。

|After Effectsでの表示|端末での表示|
|:--:|:--:|
|![after_effects.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186009/4fd2d136-ab97-3513-d2e0-26e25ee1944c.gif)|![ios.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186009/b21cad67-4bd9-000a-5f83-eae90662abdb.gif)|

ただ再生速度を少しずつ変えながら調整するのは、想像以上に時間を使ってしまいます。納得できるまで、「アニメーションの修正」、「JSONファイルの作成」、「アプリのリロード」を繰り返さなければならないからです。

<img width="766" alt="Screen Shot 2019-12-18 at 21.30.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186009/51b3b446-9f7a-5e31-a363-b4fda7b8d435.png">

**ちょうど良い再生速度を効率よく見つけるには...**
Lottieには、アニメーションの再生速度を変更できるパラメータがあります。lottie-react-nativeでも `speed` というパラメータに値を渡せば、設定した倍速でアニメーションを表示できます。


```react:例
import React from 'react';
import LottieView from 'lottie-react-native';

export default class BasicExample extends React.Component {
  render() {
    return (
      <LottieView
        source={require('./animation.json')}
        speed={0.5} // ここに設定した倍速でアニメーションが表示されます（例: 0.5倍速）
        autoPlay
      />
    );
  }
}
```

`speed` を変更する方法であれば、確認の度にアニメーションを修正する必要はなくなるので、効率よくちょうど良い再生速度を見つけることができます。

<img width="827" alt="Screen Shot 2019-12-18 at 22.06.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186009/b2060e49-872a-a407-b8dc-175745db9c4c.png">

ちょうどよい再生速度がわかったあと、 `speed` に設定した値を参考にアニメーションを変更し、新しくJSONファイルを作成すれば完成です。

## 最後に
React NativeにLottieアニメーションを実装したときの苦労話について書いてきましたが、今回紹介したことさえ気をつければ、わりと簡単にアニメーションを組み込むことができるのではないかと思っています！

自分が作ったアニメーションや気に入ったアニメーションをアプリ上で表示させるのは、とても楽しいです！みなさんもぜひLottieを使って遊んでみてはいかがでしょうか！

ちなみに[LottieFiles](https://lottiefiles.com/featured)というサイトに行けば、Lottieアニメーション用のJSONファイルを簡単に入手できちゃいます🤫

続きまして、React Native Advent Calendar 19日目の記事は @ovama-koffee さんの「AndroidのNative module解説」です :tada: