VYBE 動態設計
動態即是訊息。每個動作都必須傳達關於主體的某種特性—— 重量、速度、自信、驚奇——否則它就不該存在。
所有配方皆適用於 HyperFrames:每個合成中一個暫停的 GSAP 時間軸,
確定性、可尋。使用 fromTo 處理進場,使用變形 + 不透明度 +
clipPath + filter 處理動畫,絕不修改佈局屬性。
參考文件(依據需求載入)
| 檔案 | 用途 |
|---|---|
references/animation-principles.md | 12 項原則應用於 UI/文字/圖形、緩動詞彙表、時間表 |
references/transitions.md | 14 種含 GSAP 程式碼的轉場配方,以及使用時機 |
references/camera-movements.md | 推軌、橫移、升降、環繞、穿越變焦、甩鏡、焦點偏移、視差 — 2D 與 3D |
references/visual-effects.md | 光暈、綻放、漏光、底片顆粒、色散、動態模糊、遮罩、形變 |
十項規則
- 編舞,而非動畫。 規劃誰先移動、誰回應、誰保持不動。 一個場景如同一句話:主詞 → 動詞 → 受詞。
- 緩動即個性。
expo.out= 高級/自信;back.out= 俏皮;power2.inOut= 機械攝影機;sine.inOut= 呼吸感/環境;none= 持續漂移。每部電影選用 2-3 種緩動並保持一致。 - 快速進入,緩慢穩定。 多數進場:0.5–0.9 秒,在前 30% 的時間內完成 80% 的移動。
- 出場比進場更快(約 60%)並使用
.in緩動。 - 交錯顯示層次 — 字母間隔 0.04–0.08 秒、單詞間隔 0.1–0.18 秒、 列表項目間隔 0.3–0.6 秒。切勿完全一致地交錯所有元素。
- 動作重疊。 下一個元素在前一個完成之前開始
(位置參數
"<0.2"/ 絕對時間)。依序 = 機械感。 - 停留以閱讀。 每個詞約 0.3 秒 + 0.5 秒;結尾行至少 2 秒。
- 保持生機。 在停留期間,緩慢推進(
scale 1→1.04)、漂移 或光掃描可防止畫面停滯 — 但每層僅一種環境動態。 - 變化轉場。 每部影片至多一次黑幕淡變。優先選擇動作剪輯、 匹配剪輯、遮罩擦拭、穿越變焦、共享元素。
- 尊重節拍。 若有音樂,每個主要變化應落在拍子上
(
60/bpm);重拍落於正拍,預先準備則在拍子前開始。
可尋的 GSAP 模式
const tl = gsap.timeline({ paused: true });
// 進場:模糊至清晰上升(高級感)
tl.fromTo("#s1-title", { opacity: 0, y: 40, filter: "blur(12px)" },
{ opacity: 1, y: 0, filter: "blur(0px)", duration: 0.9, ease: "expo.out" }, 0.2);
// 遮罩擦拭揭示(編輯風格)
tl.fromTo("#s1-line", { clipPath: "inset(0 100% 0 0)" }, { clipPath: "inset(0 0% 0 0)", duration: 0.8, ease: "expo.inOut" }, 0.5);
// 逐字元擴散(取代 letterSpacing — 因其會被 lint 拒絕)
gsap.utils.toArray("#s1-word .ch").forEach((c, i, all) => {
const off = (i - (all.length - 1) / 2) * -30;
tl.fromTo(c, { x: off, opacity: 0 }, { x: 0, opacity: 1, duration: 1, ease: "expo.out" }, 1 + Math.abs(i - (all.length - 1) / 2) * 0.05);
});
// 數字遞增(可尋:onUpdate 在每次尋道時執行)
const n = { v: 0 }, el = document.getElementById("s1-num");
tl.fromTo(n, { v: 0 }, { v: 97, duration: 1.4, ease: "expo.out", onUpdate: () => (el.textContent = Math.round(n.v)) }, 1.2);
// 環境停留動畫
tl.fromTo("#s1-stack", { scale: 1 }, { scale: 1.04, duration: 3, ease: "sine.inOut" }, 0);
window.__timelines["s1"] = tl;
文字分割:將單詞/字母包裹在 <span class="w|ch" style="display:inline-block">
(變形對行內元素無效)。將空白保留在 span 外。
交付前檢查
- 無連續兩個場景使用相同的進場動態。
- 無重疊時間內對同一元素重複補間相同屬性。
npx hyperframes checkMotion 部分乾淨;若要進行編舞審計,請執行 HyperFrames 安裝後附帶的animation-map.mjs腳本(位於/hyperframes-animation技能中)。