前幾篇文章介紹了一些 Rive 的功能與使用方式,這次想換個角度,直接從 Marketplace 上的案例出發,看看 Rive 是如何設計一個完整的互動體驗。
Marketplace 上其實有不少很有趣的範例,但第一次看到 Spinwheel Interaction 時,我的第一個反應其實是:「這不就是一個抽獎轉盤嗎?」直到實際玩了一下才發現,它真正想展示的不是轉盤,而是整個互動流程。

如果今天要用 HTML、CSS 和 JavaScript 製作這個轉盤,相信大部分前端工程師都會有一套熟悉的做法。我們會先將轉盤畫出來,再利用 transform: rotate() 搭配 transition 或 animation 控制旋轉效果,最後透過 JavaScript 計算停止的位置,決定要停在哪一個獎項。
單純讓轉盤旋轉並不困難,但實際產品往往還會加入更多互動細節,例如按鈕的按壓回饋、旋轉時的加減速、光效、指針震動,以及最後的結果揭曉動畫。隨著需求增加,前端除了處理商業邏輯,也需要負責串接整個動畫流程。
久而久之,動畫的狀態、播放時機與各種細節都會散落在程式碼中,每新增一個效果,都可能需要調整原有邏輯。對工程師而言,動畫不再只是畫面呈現,而是逐漸成為需要維護的一部分程式。
而 Spinwheel Interaction 剛好展示了另一種做法:讓動畫本身也參與互動流程的管理。
在看 Spinwheel Interaction 這個案例時,我覺得有趣的地方並不是轉盤旋轉本身,而是它如何把一次抽獎操作設計成一段完整的互動體驗。
當使用者按下按鈕時,轉盤並不會直接開始旋轉,而是先透過按鈕縮放、發光等細節回應操作,接著經過加速、旋轉、減速,最後停留在結果位置並播放揭曉動畫。
如果只是做出「會旋轉的轉盤」,其實並不困難。但真正影響使用者感受的,是每個階段之間的節奏與回饋,讓等待結果的過程也成為體驗的一部分。
這也是這個案例有趣的地方:動畫不只是被程式觸發後播放,而是本身就具備互動流程。
透過 State Machine,設計師可以在 Rive 中定義轉盤不同階段的狀態,例如等待操作、開始旋轉、減速停止以及結果展示。前端只需要透過 Input 告訴 Rive 發生了什麼事件,剩下的狀態切換與動畫節奏則交由 Rive 管理。
這樣的分工讓前端專注在資料與商業邏輯,例如取得抽獎結果、傳遞必要參數;Rive 則負責互動體驗,例如動畫節奏、狀態轉換與視覺回饋。當需要調整動畫細節時,也只需要更新 .riv 檔案,而不需要修改原本的程式流程。
比較 CSS 與 Rive 的做法後,我覺得最大的差異並不是誰做出的動畫比較漂亮,而是動畫邏輯放在哪裡。
使用 CSS 製作動畫時,工程師通常需要自己控制動畫的開始、結束,以及不同效果之間的銜接。當互動越來越複雜,動畫狀態也會逐漸變成程式需要維護的一部分。
而在 Rive 中,動畫不只是視覺效果,也可以成為一個具有狀態的互動元件。工程師不需要描述每一個細節,而是告訴 Rive「現在發生了什麼事情」,例如使用者按下按鈕、開始旋轉或顯示結果,再由 State Machine 決定接下來的呈現方式。
這個概念其實很像遊戲角色控制。程式不會每一幀告訴角色手要抬多高、腳要移動多少,而是切換角色目前的狀態,例如 Idle、Run 或 Attack,再由動畫系統播放對應動作。
Spinwheel Interaction 值得拿來作為 Case Study,不只是因為它完成了一個流暢的轉盤動畫,而是因為它展示了另一種設計互動的方式。
如果只是單純的旋轉、淡入淡出或位移動畫,CSS 依然是快速且成熟的選擇。但當互動開始包含多個狀態切換、豐富的視覺回饋,以及需要反覆調整動畫細節時,將部分邏輯交給動畫本身管理,會是一種不同的思考方式。
透過 Spinwheel Interaction 可以看到,動畫不一定只能被程式控制播放。程式負責描述「發生了什麼事情」,而動畫則負責決定「這件事情如何呈現」。