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


私が所属する会社では 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 を調査しようと思います。