「トランジション採用」でフリーランスの正社員転換を支援 他
- 隔週月曜更新!フリーランス・副業ニュース
react-three-fiberは、Three.jsのためのReactレンダラー。動的なシーングラフを簡単に作れる優れものです。
今回はこのreact-three-fiberを使って、シーングラフを再利用可能なコンポーネントに分離し、アニメーションをつける方法をご紹介します。
Reactとは、Facebookが開発したJavaScriptライブラリです。頭に浮かんだアイデアを、レゴブロックのようにコンポーネントに変身させられるのが特徴です。
しかしそんなReactにも、コンポーネントの処理方法を指示するための調整プログラムが必要ですあ。調整プログラムには、ARやVRなどさまざまなプラットフォームにリーチするものがありますが、その中でもreact-three-fiberはコンポーネントをThree.jsのシーングラフに変換してくれるものとなります。
react-three-fiberの「Canvas」コンポーネントが、Three.jsへのポータルです。ここに入るものはすべて、Three.js固有のオブジェクトになります。
以下で作成しているのは、ライトがついたレスポンシブキャンバスです。
function App() {
return (
<Canvas>
<ambientLight intensity={0.5} />
<spotLight intensity={0.5} position={[300, 300, 4000]} />
</Canvas>
)
}
今回のゴールはSVGパスを抽出し、それぞれ別個にアニメーションを加えることです。そのためあまりレイヤーが多くない、シンプルなイラストを使用するのが良いでしょう。
Three.jsのSVGLoderを使って、SVGをジオメトリに変換しましょう。
以下は、図形と色を含むオブジェクトのネストした配列です。Z座標を指定するためのindexも収集します。
const svgResource = new Promise(resolve =>
new loader().load(url, shapes =>
resolve(
flatten(
shapes.map((group, index) =>
group.toShapes(true).map(shape => ({ shape, color: group.color, index }))
)
)
)
)
)
次に、図形をレンダリングする「Shape」コンポーネントを定義します。それぞれの図形は、indexによって50ユニットにオフセットされています。
function Shape({ shape, position, color, opacity, index }) {
return (
<mesh position={[0, 0, index * 50]}>
<meshPhongMaterial attach="material" color={color} />
<shapeBufferGeometry attach="geometry" args={[shape]} />
</mesh>
)
}
次に必要なのが、作成した図形をマッピングするコンポーネントです。先ほど作ったリソースがロードされたら、ローカルコンポーネントのstateに書き込み、作成しておいた「Shape」コンポーネントに各図形を転送します。
function Scene() {
const [shapes, set] = useState([])
useEffect(() => void svgResource.then(set), [])
return (
<group>
{shapes.map(item => <Shape key={item.shape.uuid} {...item} />)}
</group>
)
}
これで、キャンバスにSVGが表示されます。
Three.jsにアニメーションをつけたい場合は、GSAPなどのツールを使うのがおすすめです。
今回はアニメーションを調整するためのシステムが必要ですが、これを構築するのは簡単ではありません。しかし今回はReactコンポーネントをレンダリングしているため、アニメーションやトランジションツールなど、エコシステムに存在するものはほとんどすべて使用できるのです。今回はreact-springを使います。
このステップで行うべきことは、図形をtransition-groupに変換することです。transition-groupはstateの変化を監視し、安全に削除できるようになるまで古いstateを保持して遷移させるのに役立ちます。
react-springの場合、これを「useTransition」と呼びます。元のデータ(ここでは図形)、データセットの変更を識別するためのkey、そしてstateが追加・削除・または変更された際に、useTransitionは何を実行するかを定義できるのです。
そして、すべてを網羅しているのが以下です。追加された図形は、sceneに軌道を残すかたちでトランジションします。また削除されると、トランジションアウトします。
const transitions = useTransition(shapes, item => item.shape.uuid, {
from: { position: [0, 50, -200], opacity: 0 },
enter: { position: [0, 0, 0], opacity: 1 },
leave: { position: [0, -50, 10], opacity: 0 },
})
return (
<group>
{transitions.map(({ item, key, props }) => <Shape key={key} {...item} {...props} />)}
</group>
)
useTransitionは、生成されたkey、元のデータ(ここでは図形)、アニメーション化されたプロパティを含むオブジェクトの、それぞれの配列を作成します。すべてをShapeコンポーネントに展開したら、あとはアニメーション化した値を受け取るためにそのコンポーネントを準備するだけです。
react-springは、「animated」と呼ばれるヘルパーと、「a」と呼ばれるショートカットをエクスポートします。これを使ってエレメントを拡張すると、これらのプロパティが処理できるようになります。基本的に、divがあれば「a.div」になり、meshがあれば「a.mesh」になります。
今回の記事を読んでみて、「react-three-fiberとreact-springについてもっと詳しく知りたい!」と思った方もいるのではないでしょうか。そんなときは、ぜひ上記のそれぞれのリンクをクリックして、説明を読んでみてください。英語ではありますが、一番詳しく解説されているはずです。
オリジナルデモに必要なコードはこちらから確認できます。
(原文:Paul Henschel 翻訳:Asuka Nakajima)
こちらもおすすめ!▼
【SVGフィルタ講座①】基本的な使い方&画像にぼかし効果を加える方法
Workship MAGAZINE
たった3ステップ!WebGLを使ってインタラクティブな3D風写真を作ろう
Workship MAGAZINE