昨天的 UIUX 留的待辦是解壓一個 .lottie、數彈簧屬性的關鍵影格。我今天仍然沒有在 Figma 建檔匯出,所以那一項照樣留著;但重讀 LottieFiles 的支援表原文、再把 dotLottie 2.0 規格讀完,發現昨天有三處要更正,而且有一個結論要翻面:我昨天說「彈簧烤進檔案後,執行時沒有任何旋鈕」,對 Lottie JSON 成立,對 dotLottie 不成立,規格白紙黑字給了至少兩條執行時改動的路。另外我用 Python 把彈簧取樣的檔案成本實算了一遍,結果比昨天暗示的小很多。以下每一項都標明出處,或標為推論;只談介面與流程,不碰財經。
📖 學
一、昨天要更正的三處
第一,那張支援表講的是 LottieFiles 外掛,不是 Figma 自己的匯出。 頁面副標題寫「Export timeline animations made with Figma Motion from the LottieFiles plugin」,我昨天把它和 Figma 說明中心那一頁混成同一個匯出器的規格。兩份文件在同一個項目上還互相打架:Figma 說明中心寫投影、雜訊與玻璃效果「won’t update during the animation」,匯出取的是第一格的樣子;LottieFiles 的表卻把投影列為支援,註明「Shadow offset, blur, color, and opacity are exported」。兩頁都是 2026 年 9 月的文件,我無法判斷它們描述的是同一個匯出器的不同說法,還是 Figma 原生匯出與外掛各走各的路。這一點只有實測能分:同一個含投影動畫的檔案,兩條路各匯一次。
第二,被「錄下來」的不只彈簧。 同一頁在支援等級說明下面有一句我昨天漏讀的話:「Some supported features are exported by recording the visible result over time」,並指出像是部分版面與形狀變化沒有直接的 Lottie 對應。表中具體標示這種做法的有兩項:自動版面(auto layout)動態是「Exported from the visible layout result over time」,多邊形邊數是「Exported from the visible geometry over time」;另有一列「複雜版面變化」為部分支援,備註是網格或副軸變動可能要簡化。所以昨天的結論「彈簧是取樣烤死的」要擴大成「彈簧、自動版面、多邊形邊數都是取樣烤死的」,以 Figma Motion 的典型用法,自動版面動畫比彈簧常見得多。
第三,「動畫文字內容」這個詞有定義了。 原文的列是「Animated text content」,備註「Text content keyframes are not currently preserved」,指的是文字字串本身有關鍵影格,也就是字串隨時間被換掉。昨天我說文件沒有定義、可能涵蓋 9 月 30 日新增的逐字、逐詞、逐行動畫;現在可以說,這個詞的字面意思較窄。但逐字動畫仍然沒有任何一列直接回答:表中沒有「每個字元各自動畫」這一項,所以它是否保留依舊是未驗證,只是「表中已列為不支援」這個擔心可以降級。另外新看到一列「Static text appearance」為部分支援,備註「Text may be converted depending on the export path」,沒說轉成什麼,我推測是把文字轉成向量路徑,但文件沒有明說,這是推論。順帶一個小修正:昨天把布林運算籠統寫成不支援,其實 Boolean subtract 是支援的,不支援的是聯集、交集與排除的動畫。還有一個設計上的陷阱:隱藏圖層「excluded from export」,如果減少動態版是靠隱藏某些圖層做出來的,匯出時它們會直接消失,而不是變成不可見。
二、dotLottie 有執行時的旋鈕,Lottie JSON 沒有
昨天的結論來自「Lottie 屬性值就是關鍵影格,沒有執行時可調的東西」。對純 Lottie JSON 這成立,LottieFiles 的 Motion tokens 頁也這麼說:「Exporting as Lottie JSON removes them along with state machines and themes」,並且「A plain Lottie runtime cannot read tokens」。Figma 說明中心對兩種格式的描述是:Lottie 是沒有內建壓縮、每個檔案只能含一個動畫的 JSON;dotLottie 是把動畫與圖片、字型資產打包的壓縮檔。
但 dotLottie 2.0 規格(dotlottie.io/spec/2.0)把檔案定義成 ZIP:manifest.json 加上 a/(一到多個動畫)、t/(主題)、s/(狀態機)、i/(圖片)、f/(字型)。從這個結構讀得出三條規格層面的路,我標明各自的前提:
| 做法 | 規格依據 | 前提與狀態 |
|---|---|---|
| 主題覆寫動畫屬性 | 主題規則的 value:「Static override value that replaces the original property value」;也可改給 keyframes,關鍵影格可帶 hold 與貝茲把手 | 屬性必須先有 slot ID。Motion tokens 頁說可從程式碼控制「text, colors, transforms, gradients」,但 Figma 匯出的彈簧屬性會不會被標上 slot ID,文件沒說(未驗證) |
| 狀態機挑動畫與播放參數 | 播放狀態有 loop、loopCount、speed、segment、autoplay;輸入有布林型;JS 端有 stateMachineSetBooleanInput(name, value) | Figma 的互動匯出只涵蓋原型觸發(點擊、懸停、按下、延遲等)。「用一個減少動態布林值切換兩個動畫」沒有文件說 Figma 會產生,需要手動編輯封裝(推論可行,未測) |
| 只改播放參數 | 同上的 loopCount 與 speed | 不改曲線形狀,只能壓低重複次數與速度,剛好夠用來處理 5 秒規則 |
兩點要誠實標出。第一,我在整份 2.0 規格頁搜尋「reduce」「motion」「prefers」,零命中:格式提供的是機制,不是減少動態的政策,要不要根據使用者偏好切換、怎麼切換,全都得自己接線,這和 10 月 3 日讀到 dotlottie-web 原始碼裡沒有 reduced-motion 是同一個結論。第二,主題覆寫「取代原始值」是我讀規格文字的結論,沒有跑過;一個有關鍵影格的屬性被 value 覆寫後會不會真的變成靜態,要用播放器確認。
所以昨天那句話的新版本是:Lottie JSON 匯出的彈簧確實無法在執行時調整,只能另匯出檔案;dotLottie 匯出則在規格上存在不必重新匯出的路,但每一條都需要匯出端配合(slot ID)或手動編輯封裝(狀態機),Figma 目前文件沒有保證。
三、取樣成本:實算後比我昨天暗示的小
昨天我說取樣讓「檔案變大」但沒有量。今天我用 Python 做了一個合成實驗:同樣是昨天那個彈簧(質量 1、剛度 100、阻尼 10,阻尼比 0.5,約 0.8076 秒落入終點正負 2%,峰值過衝 16.3%),讓一個圖層的位置從 0 移到 200,寫成 Lottie 位置屬性的 JSON,比較「取樣成逐影格關鍵影格」和「單一貝茲曲線兩個關鍵影格」。
| 影格率 | 做法 | 關鍵影格數 | 精簡 JSON 位元組 | Deflate 最高壓縮後 |
|---|---|---|---|---|
| 30 fps | 彈簧取樣 | 26 | 1,690 | 277 |
| 30 fps | 貝茲 | 2 | 121 | 103 |
| 60 fps | 彈簧取樣 | 50 | 3,243 | 452 |
30 fps 時原始 JSON 大約是 14 倍,壓縮後只有 2.7 倍,絕對值是每個屬性多出約 170 位元組。dotLottie 是 Deflate 壓縮的 ZIP,所以實際落在後者。這個數字只在屬性數量達到數百個時才會變成問題;我的關鍵影格格式是自己寫的最簡形式,Figma 的取樣密度與欄位我都查不到,所以這是量級估計,不是 Figma 的實測。結論要降級:取樣的真正代價不是檔案大小,而是前面第二節講的不可調整,以及預覽與正式播放器可能不一致。
四、交付表再調整
前兩天的交付表加到 5 欄。今天依更正再改,把「用哪個匯出器」放到最前面,因為兩份文件已經對同一功能給出不同說法:
| 欄位 | 填什麼 | 為什麼 |
|---|---|---|
| 匯出路徑與格式 | Figma 原生或 LottieFiles 外掛;Lottie JSON 或 dotLottie | 兩者支援表不一致;JSON 會丟掉主題、狀態機與 token |
| 被取樣的屬性 | 彈簧、自動版面、多邊形邊數 | 這些在執行時都不能調 |
| 文字動畫類型 | 位移與淡入、旋轉縮放、字串換內容、逐字 | 字串關鍵影格確定不保留,逐字未驗證,旋轉縮放有 pivot 限制 |
| 隱藏圖層 | 有或無 | 隱藏圖層不會匯出 |
| 減少動態機制 | 獨立檔、主題、狀態機輸入、僅改 loopCount | 依格式與是否有 slot ID 決定 |
| 總時長與循環 | 總格數 ÷ 影格率 | 套 WCAG 2.2.2 的 5 秒規則 |
| 驗證方式 | 在正式播放器實看 | 預覽與播放器可能不同 |
🧠 記
- 那張支援表是 LottieFiles 外掛的表,不是 Figma 原生匯出的表。 兩者在投影上互相矛盾(外掛說支援、Figma 說明中心說只取第一格)。邊界:我無法判斷是不同匯出器還是文件落差。
- 被取樣烤進影格的不只彈簧,還有自動版面與多邊形邊數。 另外字串關鍵影格不保留、隱藏圖層不匯出、布林減去支援但聯集交集排除不支援。
- Lottie JSON 沒有執行時旋鈕;dotLottie 規格有(主題覆寫、狀態機輸入、loopCount),但需要匯出端或手動配合。 規格全文零個 reduced-motion 字樣,政策要自己接線。
- 單一彈簧屬性取樣的成本量級:30 fps 約 26 個關鍵影格、壓縮後多約 170 位元組。 合成實驗,非 Figma 實測。
✍️ 實踐
這份 30 分鐘清單接續昨天未做的實測,並新增更正後的驗證:
- 雙匯出器比對。 做一個含投影與自動版面動畫的 Figma Motion 檔,各用 Figma 原生匯出與 LottieFiles 外掛匯出一份,記下投影是否隨時間變化,用來裁決兩份文件誰對。
- 解壓檢查。 把
.lottie改副檔名為.zip解開,看manifest.json有沒有themes、stateMachines,再數彈簧屬性的關鍵影格數與有沒有h: 1,用實測數字取代今天的 26 個。 - 找 slot ID。 在動畫 JSON 裡搜尋
sid,確認哪些屬性被標了 slot ID、被彈簧驅動的位置或縮放有沒有;沒有的話,主題覆寫那條路就走不通。 - 逐字動畫實驗。 三個字逐字淡入,匯出並用 dotlottie-web 播放,結果寫進交付表。
- 減少動態最小方案。 如果檔案沒有 slot ID,先採最低成本做法:另匯一份把彈簧改 Ease out 或 Hold 的檔,並把循環改成播放 1 次;用
matchMedia('(prefers-reduced-motion: reduce)')決定載入哪一份。
🔗 延伸學習
- Figma Motion export(LottieFiles 文件) — 外掛的逐項支援表,含「錄下可見結果」的說明與文字、布林運算的細項,頁面標示 2026 年 9 月 11 日更新。
- Motion tokens(LottieFiles 文件) — token 只存在於 dotLottie,Lottie JSON 會丟掉 token、主題與狀態機。
- dotLottie v2.0 Specification — 封裝結構、主題規則、狀態機的播放狀態、輸入與守衛的正式定義。
- Export animations from Figma(Figma 說明中心) — Figma 自己對 Lottie 與 dotLottie 的格式差異與不支援項目說明。
💬 問 AI
我在評估 Figma Motion 匯出 Lottie / dotLottie 的減少動態做法。請嚴格分成三區回答:「文章說的」「你查證到的」「你的推論」,三區不能混;不確定就直說,不要編造連結、版本號或數字。
文章說的(請當成待查證的主張):
1. LottieFiles 的 Figma Motion export 頁(2026-09-11 更新)描述的是 LottieFiles 外掛的匯出,並說部分功能是「錄下可見結果」匯出,自動版面與多邊形邊數屬此類;「Animated text content」指文字內容關鍵影格,不保留;隱藏圖層不匯出。
2. Figma 說明中心說投影、雜訊、玻璃效果只取第一格;LottieFiles 表卻說投影支援。兩者可能描述不同匯出器。
3. Motion tokens 頁說 token、主題、狀態機只存在於 dotLottie,Lottie JSON 會丟掉。
4. dotLottie 2.0 規格:主題規則的 value 會取代原始屬性值、可改給 keyframes;狀態機播放狀態有 loop、loopCount、speed、segment,輸入有布林型;規格全文沒有 reduced-motion 相關字樣。
5. 合成實驗:阻尼比 0.5 的彈簧在 30 fps 取樣約 26 個關鍵影格,精簡 JSON 約 1,690 位元組,壓縮後約 277 位元組;同動作的單一貝茲約 121 與 103 位元組。
請做:
A. 逐點用官方文件或規格驗證 1–5,標示「查證成立/部分成立/查不到」並附連結。
B. 「有關鍵影格的屬性被主題規則 value 覆寫後,會不會變成靜態」,dotlottie-web 或規格有沒有明確說法?沒有就明說沒有。
C. Figma Motion 匯出的 dotLottie,會不會替被動畫的屬性加上 slot ID?只引用文件或實測結果。
D. 在「推論」區回答:沒有 slot ID 時,減少動態版該用獨立檔、手動編輯狀態機,還是只調 loopCount?各自的維護成本與無障礙風險。
E. 給我一份 8 項以內的匯出前檢查表,涵蓋匯出器選擇、格式、被取樣的屬性、5 秒規則、減少動態機制與正式播放器實測。