React Native Skiaとは何か
React Native Skiaが何を解決するライブラリなのか、標準のView/SVGベースの描画との違いを中心に紹介します。
標準UIの部品を積み重ねる発想から、1枚のCanvasでピクセルまで制御する発想へ。
React Native Skiaは、Google Chrome・Android・Flutterなどが採用しているグラフィックエンジン、Skia(スキア)をReact Nativeから直接使えるようにするライブラリです。Shopifyが開発・公開しており、円やパスといった基本図形からシェーダー(Shader)まで、GPU上で動く本格的な2D描画をReactの宣言的なコンポーネントとして書けます。
Viewの積み重ねでは足りない場面
React Nativeの標準的なUIは、ViewやTextをネストしてStyleSheetで見た目を整える方式で作られています。角丸のカード、影付きのボタン、単純なグラデーションくらいまでは、この方法で十分にきれいに作れます。
ただし、次のような表現になると途端に難しくなります。
- 2つの色を任意の形状に沿ってなめらかに混ぜるグラデーション
- パスに沿って変形するアニメーション(波打つ線、モーフィングする図形)
- ぼかしやノイズ、色収差といったピクセル単位のエフェクト
- 数百〜数千個のオブジェクトを毎フレーム再配置する表現(パーティクル、チャート)
Viewは最終的にネイティブのUIコンポーネント(iOSのUIView、AndroidのView)に変換されるため、こうした表現は各プラットフォームのグラフィックAPIを直接叩かない限り実現できません。React Nativeの中だけで完結させようとすると、途端に選択肢が乏しくなります。
SVGとの違い
もう一つの選択肢であるreact-native-svgは、パスやグラデーションを宣言的に書けるという点でSkiaと似ています。しかし、SVGはベクター画像フォーマットの仕様に沿ったAPIなので、表現できる範囲もその仕様に縛られます。
対してSkiaは、SVGのようなドキュメントフォーマットではなく、それ自体が汎用の2D描画エンジンです。パスやグラデーションはもちろん、ピクセル単位で計算するシェーダー(Shader)、画像に効果をかけるイメージフィルター(Image Filter)、複数の描画結果を合成する**ブレンドモード(Blend Mode)**まで、一つの一貫したAPIの上に乗っています。SVGでは表現の範囲外だったエフェクトも、Skiaでは同じ<Canvas>の中で組み合わせて書けます。
GPU描画だからできること
Skiaは描画命令をCPU側で組み立てたあと、実際のピクセル計算をGPUに渡します。iOSではMetal、AndroidではOpenGL(一部Graphite経由でVulkan)が使われ、フレームごとに大量のピクセルを並列に処理します。
この仕組みのおかげで、React Native Skiaは次のようなことが得意です。
- 複雑なシェーダーやフィルターを毎フレーム描き直しても滑らかに動く
- Reanimatedの共有値(Shared Value)を直接描画プロパティに渡し、UIスレッドを介さずアニメーションできる
- 画像・パス・テキストを同じ座標系の中で自由に重ね合わせられる
もちろんViewベースのUIがすべてSkiaに置き換わるべきというわけではありません。通常のボタンやリストは、これまで通りRNの標準コンポーネントで作るのが最も効率的です。Skiaが真価を発揮するのは、標準コンポーネントの表現力を超えた描画やアニメーションが必要になったときです。
できることショーケース
React Native Skiaで書けることの幅を、いくつかの例で見てみましょう(具体的な書き方は第2部以降で扱います)。
図形とグラデーションの組み合わせ
CircleやRectといった基本図形にLinearGradientやRadialGradientを塗りとして与えると、単色では出せない奥行きのある表現になります。
<Canvas style={{ flex: 1 }}>
<Circle cx={128} cy={128} r={100}>
<LinearGradient
start={vec(0, 0)}
end={vec(256, 256)}
colors={["#4c1d95", "#db2777"]}
/>
</Circle>
</Canvas>
シェーダーによる表現
SkSLという専用のシェーダー言語で書いた処理を、RuntimeShaderとして図形の塗りに使えます。時間を渡せば、揺らめくノイズや流体のような動きも作れます(第4部で詳しく扱います)。
アニメーションとの統合
Reanimatedの共有値をそのままcxやrといった描画プロパティに渡すだけで、UIスレッド上で動くアニメーションになります。ジェスチャーと組み合わせれば、指の動きに直結した描画も自然に書けます(第5部で扱います)。
これらはすべて同じ<Canvas>コンポーネントの中で、Reactのコンポーネントツリーとして組み立てます。次の章では、この宣言的な書き方が実際にどうやってGPUの描画命令に変換されるのか、しくみを見ていきます。
React Native Skiaの全体像は、公式ドキュメントにもまとまっています。