Help us understand the problem. What is going on with this article?

lottie-react-native がアニメーションを描画する仕組み(ネイティブブリッジまで)

More than 1 year has passed since last update.

私が所属する会社では lottie-react-native というライブラリを使用してアニメーションを描画しています。

私は lottie-react-native の導入を担当したこともあり、ライブラリの使い方については把握しています。しかし、アニメーションが描画される仕組みは理解できていないので、調査してみることにします。

lottie-react-native は各 OS の Lottie ライブラリを利用

lottie-react-native を利用してアニメーションを描画する際は、 LottieView コンポーネントを使用します。

サンプルコード
import React from 'react';
import LottieView from 'lottie-react-native';

export default class BasicExample extends React.Component {
  render() {
    return <LottieView source={require('./animation.json')} autoPlay loop />;
  }
}

ソースコードを読むと、ネイティブ層で実装している LottieAnimationViewLottieView コンポーネントの内部で呼び出されていることがわかります。

/src/js/LottieView.js
const NativeLottieView = SafeModule.component({
  viewName: 'LottieAnimationView',
  mockComponent: View,
});

iOS 側の LottieAnimationViewAnimationViewManagerModule.swift というファイルで実装されています。そのファイルでは lottie-iosLottie モジュールがインポートされています。

/src/ios/LottieReactNative/AnimationViewManagerModule.swift
import Lottie

@objc(LottieAnimationView)
class AnimationViewManagerModule: RCTViewManager {

Android 側の LottieAnimationViewLottieAnimationViewManager.java というファイルで実装されています。そのファイルでは lottie-androidLottieAnimationView クラスがインポートされています。

/src/android/src/main/java/com/airbnb/android/react/lottie/LottieAnimationViewManager.java
import com.airbnb.lottie.LottieAnimationView;
...
  private static final String REACT_CLASS = "LottieAnimationView";

つまり、 lottie-react-native は各 OS の Lottie ライブラリを利用して、アニメーションを描画していることがわかります。

ネイティブブリッジ実装箇所までの辿り方

アニメーションの描画は LottieView コンポーネントを利用するので、それが実装されている /src/js/LottieView.js を確認しました。 => GitHub

アニメーションを描画しているのは render()return() しているコンポーネントです。
実装を見てみると、 AnimatedNativeLottieView というコンポーネントが返っています。

/src/js/LottieView.js
    return (
      <View style={[aspectRatioStyle, sizeStyle, style]}>
        <AnimatedNativeLottieView
          ref={this.refRoot}
          {...rest}
          speed={speed}
          style={[aspectRatioStyle, sizeStyle || { width: '100%', height: '100%' }, style]}
          sourceName={sourceName}
          sourceJson={sourceJson}
          onAnimationFinish={this.onAnimationFinish}
        />
      </View>
    );

AnimatedNativeLottieViewReact NativeAnimated.createAnimatedComponent を使用して、 animatable になったコンポーネントであることがわかりました。 => 公式ドキュメント

/src/js/LottieView.js
const AnimatedNativeLottieView = Animated.createAnimatedComponent(NativeLottieView);

引数に渡している NativeLottieView が、ネイティブ層で定義されている LottieAnimationView であることがわかり、ネイティブブリッジしていることがわかりました。

/src/js/LottieView.js
const NativeLottieView = SafeModule.component({
  viewName: 'LottieAnimationView',
  mockComponent: View,
});

次回は各 OS の Lottie ライブラリを調査

今回の調査で、アニメーションを描画する仕組みが各 OS の Lottie ライブラリで実装されていることがわかりました。

アニメーションを描画する Lottie の仕組みを探るため、次回は各 OS の Lottie ライブラリである lottie-ios と lottie-android を調査しようと思います。

tamago3keran
React Nativeでアプリ開発を行っています。 アニメーションが好きで、Adobe After Effectsでアニメーションを作成して、Lottieを使ってアプリに組み込んだりしています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away