1仕組みと動作原理
出力ショット:同梱のGeistフォントをTTF解析とポリゴンオフセットにより押し出しワイヤーフレームグリフとして生成し、「ポータルの破裂」から出現(破裂のカオス度は調整可能)。第2拍で文字が代替フレーズへと入れ替わります。
Extruded wireframe letterforms are built from the bundled Geist face with a TTF loader and polygon offsetting, then revealed through a portal burst whose chaos is a variable. … A second beat swaps the letters into a replacement phrase with whole-word wrapping and auto type size, staggered with a tunable easing curve and settle glitch, with optional depth fog.
デュアルキャンバス階層構造:立体層(wpt-three)と歪み層(wpt-warp)は両方ともランタイム時に生成され、静的マークアップ内に<canvas>は存在しません。
["wpt-three", "wpt-warp"].forEach(function (id) { var canvas = document.createElement("canvas"); canvas.id = id; canvas.width = 1920; canvas.height = 1080;
オフスクリーンcanvasによる実測タイポグラフィ:Geist 700 176pxを基準に1文字ずつ幅を実測し、3%の字間を追加。その上で単語単位の改行とフォントサイズの自動調整を行います。
const measure = document.createElement("canvas").getContext("2d"); measure.font = "700 176px Geist"; const tracking = 176 * 0.03; const advance = (char) => measure.measureText(char).width + tracking;
フォントはローカルアセット:ホスト提供のassetUrl("assets/fonts/Geist-Bold.ttf")経由でArrayBufferを取得し、TTFLoader/FontLoaderに渡して解析します。
const ttfBuffer = await fetch(assetUrl("assets/fonts/Geist-Bold.ttf")).then((r) => r.arrayBuffer(), ); const font = new FontLoader().parse(new TTFLoader().parse(ttfBuffer));
ランダム性を元の実験コードのMath.randomから2つの独立したシード値に置換:シーン用(20260824)とフレーズの時間差用(20260831)に分け、文字置換と破裂の再現性を担保。
// ---------- seeded PRNG (replaces the experiment's Math.random) ---------- … const rand = mulberry32(20260824); const phraseRand = mulberry32(20260831);
初手フレームのウォームアップを行う明確な理由:t=0時点ではポータルが閉じており何も描画されないため、再生中の初回実描画まで待つと全シェーダーのリンク処理が再生負荷となってしまいます。
The portal is closed at t=0 and draws nothing, so the first real draw would link every shader mid-playback. Draw across the timeline and flush the GPU
同ファミリー共通の決定論的規約:一時停止状態のタイムラインをwindow.__timelines["wireframe-portal-title"]に登録し、hf-seekで再同期。各フレームはtの閉形式関数となります。
One paused GSAP timeline registered as `window.__timelines["wireframe-portal-title"]`. … Re-syncs on the `hf-seek` CustomEvent; every frame is a closed-form function of time (seeded PRNG only, no rAF loops, no Date.now).
2コア機能
3外部依存関係
| Kind | Dependency / Endpoint |
|---|---|
| cli | HyperFrames 官方 CLI(add / render) |
| network | jsDelivr CDN:GSAP 3.14.2(产物期脚本) |
| network | jsDelivr CDN:clipper-lib 6.4.2(多边形偏移,构建线框字形轮廓) |
| network | jsDelivr CDN:three.js 0.181.2 与 examples/jsm(importmap 解析,含后处理模块) |
| package | 本地字体(Geist ×3,OFL)随块分发;其余依赖见上(三个 CDN 脚本) |
4推奨統制措置と判定根拠
- scripts/: ローカルスクリプトまたはコマンドの実行: wireframe-portal-title.html(ブラウザ/レンダラー側で実行: 変数解析 → 2つのcanvas生成 → ワイヤーフレームグリフジオメトリ構築 → pの登録
- 网络端点: 外部ネットワークアクセスの宣言: cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js(成果物実行時: ブラウザ実行)
5二重目の独立検証
- [ok] 变量数与声明一致性(frontmatter 自称 9 variables) — 脚本实测:SKILL.md 变量表 9 行、html data-composition-variables 解析出 9 项、frontmatter 写 9 —— 一致。
- [ok] 外链清单与 SKILL.md 声称一致 — html 命中三处 jsdelivr(gsap、clipper-lib、three importmap + addons 前缀),与 SKILL.md 的 External runtime dependencies 逐项对应。
- [ok] 字体加载路径 — 字体经 assetUrl("assets/fonts/Geist-Bold.ttf") 取回;assets/fonts/ 三枚 ttf 与 OFL 文本都在盘上,registry-item 也全列(6/6 文件存在)。
- [ok] 种子化声称 — mulberry32 定义与两个常数种子(20260824 / 20260831)逐字命中;全文 grep Math.random / Date.now / requestAnimationFrame 零命中。
- [ok] 双画布与 Studio 解析器约束 — 静态 markup 中无 <canvas>;两块 canvas 由 forEach 在运行时创建(wpt-three / wpt-warp),与 SKILL.md 编辑纪律第 2 条一致。
- [ok] 首帧预热的理由是否成立 — html 注释给出可核查的理由(t=0 传送门关闭、不绘制 → 首次真绘制会链接全部 shader),且代码确在注册时间线后按 tl.time() 预绘一遍。
6結論
7c548c8702b7c0cf…