私が所属する会社では 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 />;
}
}
ソースコードを読むと、ネイティブ層で実装している LottieAnimationView が LottieView コンポーネントの内部で呼び出されていることがわかります。
const NativeLottieView = SafeModule.component({
viewName: 'LottieAnimationView',
mockComponent: View,
});
iOS 側の LottieAnimationView は AnimationViewManagerModule.swift というファイルで実装されています。そのファイルでは lottie-ios の Lottie モジュールがインポートされています。
import Lottie
@objc(LottieAnimationView)
class AnimationViewManagerModule: RCTViewManager {
Android 側の LottieAnimationView は LottieAnimationViewManager.java というファイルで実装されています。そのファイルでは lottie-android の LottieAnimationView クラスがインポートされています。
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 というコンポーネントが返っています。
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>
);
AnimatedNativeLottieView は React Native の Animated.createAnimatedComponent を使用して、 animatable になったコンポーネントであることがわかりました。 => 公式ドキュメント
const AnimatedNativeLottieView = Animated.createAnimatedComponent(NativeLottieView);
引数に渡している NativeLottieView が、ネイティブ層で定義されている LottieAnimationView であることがわかり、ネイティブブリッジしていることがわかりました。
const NativeLottieView = SafeModule.component({
viewName: 'LottieAnimationView',
mockComponent: View,
});
次回は各 OS の Lottie ライブラリを調査
今回の調査で、アニメーションを描画する仕組みが各 OS の Lottie ライブラリで実装されていることがわかりました。
アニメーションを描画する Lottie の仕組みを探るため、次回は各 OS の Lottie ライブラリである lottie-ios と lottie-android を調査しようと思います。