分1234パーティクルを初期化する関数パーティクルを初期化する関数は,前述のParticleAnimationSetオブジェクトをつくる関数(createColorAnimationSet())がParticleAnimationSet.initParticleFuncプロパティに定めたinitColorParticle()だ。プロパティParticleProperties.startTimeとParticleProperties.durationについてはよいだろう(第12回「パーティクルのアニメーションを動かす」参照⁠)⁠。パーティクルのカラーと座標は,配列の変数(colorValuesとcolorPoints)からインデックス(index)にしたがって取り出し,それぞれ引数のオブジェクト(properties)のParticleInitialColorNode.COLOR_INITIAL_COLORTRANSFORMとParticlePositionNode.POSITION_VECTOR3Dプロパティに定める。今回のアニメーションの動きを決める鍵となるのは,ParticleBezierCurveNodeのプロパティの定めだ。名前から想像がつくように,ベジエ曲線で動き方を決める。その終点(アンカーポイント)はParticleBezierCurveNode.BEZIER_END_VECTOR3D,コントロールポイントがParticleBezierCurveNode.BEZIER_CONTROL_VECTOR3Dで,ともにVector3Dオブジェクトを与える。0⁠)⁠,つまりもとの位置だ。後者は,別に定めた関数getRandomVector3D()により,引数の距離以内のランダムなVector3Dオブジェクトが与えられる。すると,パーティクルのアニメーションは,コントロールポイントにより一旦初めの位置から遠ざかり,その後終点に定めたもとの位置に戻ってくることになる。関数getRandomVector3D()の距離とふたつの角度から座標を求める計算については,第13回「パーティクルの動きにランダムな広がりを与える」を参照してほしい。関数setListeners()は,RequestAnimationFrameオブジェクトでアニメーションのコールバック関数render()を定めている。この関数からAnimatorBase.update()メソッドを呼び出した。総経過時間を引数として,アニメーションの状態が改められる。これがこのアニメーションの2つ目の鍵だ。RequestAnimationFrame()コンストラクタに渡したコールバック関数(render())は,引数として前回の呼び出しからの経過時間(deltaTime)を受け取る。その値を変数(time)に加えて,総経過時間をもたせた。ところが,AnimatorBase.update()メソッドにはこの値を直に与えず,Math.sin()メソッドで手を加えた値(_time)が渡されている。この式が,初めに掲げたサンプル1の動きをつくっているのだ。view.render();}試しに,前掲コードをつぎのように書き替えて,AnimatorBase.update()メソッドに総経過時間(time)に調整係数を乗じて引数として渡してみよう。前述のとおり,ParticleBezierCurveNodeのプロパティでベジエ曲線のコントロールポイントをランダムな距離で外側に定めたため,パーティクルはばらばらに広がり出す。終点(アンカーポイント)はもとの位置なので,やがて引き戻されていく。その先は慣性にしたがってそのまま進み続け,やがて画面の外に消えてしまう。これが,総経過時間をひたすら増やした結果だ。5);}三角関数のsinは,物理のバネ運動の式に用いられ,±1の範囲で増減を繰り返す(図3⁠)⁠。前掲の式では1を加えているので,0~2の間をバネのように変化する。調整係数で,変化の速さと幅を決めた結果,0から一定時間の間を行ったり来たりすることになった。そのため,パーティクルが広がったり,縮まったりというアニメーションを繰り返したのだ。oscillator」より。ロゴひとつをパーティクルでアニメーションさせるコード1が説明し終えた。jsdo.itに掲げたサンプル1も試してみるとよいだろう。次回からは,書き加えたコードの動きを確かめながら解説する。実は,今回のパーティクルのお題が,この連載の結びとなる。あとしばらくおつき合い願いたい。