demo_gsap の設計

設計目標

demo_gsap は、どの画も時刻の純粋関数なので、geometry3d のシーンをほかの GSAP アニメーションと同じようにスクラブ、逆再生、再再生できることを示します。JavaScript をできるだけ少なくした完全なプレーヤーページです。

数学的背景

時刻の関数としてのシーン

GSAP がタイムラインの時刻 t∈[0,8]t \in [0, 8] 秒を報告し、プログラムは render(scene(t))\text{render}(\text{scene}(t)) を描きます。前のフレームに依存するものは何もないので、任意の tt へのシーク、逆再生、別の速度での再生でも、その tt の画がそのまま表示されます。

ドリーの距離 d(t)=3.2+66.37⋅12(1+sin⁡(πt/2))d(t) = 3.2 + 66.37 \cdot \tfrac12\big(1 + \sin(\pi t/2)\big) は周期 4 秒なので、8 秒のループには 2 周期がちょうど入り、t=8t = 8 で継ぎ目なくつながります。焦点距離は f=23 d/3.2f = 23\, d / 3.2 mm に従い、demo の設計で導いたように立方体の投影サイズを一定に保ちます。トーラスの角度 1.8 t1.8\,t はループごとに 14.414.4 rad 進みますが、これは整数回転(2π⋅2.292\pi \cdot 2.29)ではないので、ループの再開時にトーラスが少し飛びます。

設計上の判断

時計は GSAP が持つ

再生の状態(一時停止、方向、速度、繰り返し、位置)はすべて GSAP のタイムラインにあり、コントロールは GsapPlayer のメソッドを直接呼びます。MoonBit のプログラムが保持するのは選択中のシーンだけです。シーンを変えると現在の時刻ですぐに描き直すので、一時停止中のプレーヤーも更新されます。

薄い JavaScript の糊付け

event.target.value の読み取り、範囲入力の設定、テキストの書き込みは 3 つの extern "js" 関数で行います。これらはページ固有で再利用されないので、バックエンドには含めていません。

正しさと不変条件

  • タイムラインの時刻 tt に表示される画は、再生ヘッドがどのように tt に達したかに依存しません。
  • ドリーのシーンはループの中で周期的ですが、トーラスのシーンはそうではありません(上記参照)。

採用しなかった案

  • MoonBit でフレームカウンタを持つことは、シークと逆再生を壊してしまいます。
  • rabbita を使って MoonBit からコントロールを組み立てることは、振る舞いを変えずにコードを増やすだけです。静的な HTML のほうが単純です。

境界

demo_gsap は API を公開せず、配布されたままの形ではオフラインで動かず、バックエンドのペインターズアルゴリズムによる並べ替えのアーティファクトも解決しません(GSAP の設計を参照)。