How do I reach 100% complete with Lottie animation ?
Introduction
日前收到了一個抽獎活動的需求:期待 visitor 點擊「抽獎」trigger 後,在過場動畫動畫完成後 freeze flow,待 visitor 點擊觀看結果後,才顯示最終結果。
由於 design team 輸出 Lottie 格式的動畫,也就是說 web page 必須要 adopt Lottie 相關的 lib 才能正常運作。
乍聽之下,這不是在簡單不過的日常嗎?!不過這其實不是那麼容易達成,由於整個 flow 中間卡了一段動畫,也就是說後續的呈現以及動作都必須要架構在「動畫有順利跑完」的前提才能正常運作。如何有效地跑完動畫便是本篇想和大家分享的主題~
Issue
看了一下 LottieDeveloper,它提供了非常多的方式予 developers,由於筆者對於 web component 情有獨鍾,因此採用了這樣的 implement 方式。它的基本用法如下所示:
用法非常簡單,基本上只要設定好 src 以及需要的 attribute 後便能獨立運作了,剩下的就是透過它所提供的 property > dotLottie 做更細緻的處理即可。最後再監聽 complete event,確保動畫完成可以有效銜接下一動作。
由範例可知,我們可以把動畫腳本放在常用的 CDN,讓它可以順利拉到檔案即可。開發完成且推機後,部分同學反應點擊抽獎後流程就中斷了,不僅沒有跑動畫,更不用說最終的結果呈現了。
經過一番測試,終於在 console 中看到了些許線索。
不知道是哪裡的設定出了問題,讓 Chrome 一直帶著我開發機的 domain 去索取檔案,自然就會被 CDN 的 CORS 設定給攔下來,也因為被攔下,所以動畫自然就不會跑,更不用說後續的動作皆需要監聽 complete event 才能運作。
所以如何順利拉到動畫腳本以及讓它跑完變成了最需要被解決的主要問題。
Solution 1
首先要做的便是確保 flow 可以有效銜接,查看一下文件發現 Lottie 其實有支援 loadError event,所以我們可以監聽這個 event,當腳本無法有效讀取的時候便可以直接 skip 動畫,直接來到後續的動作。
如上所述,筆者分別監聽 loadError / complete events,便讓它們做相同的處理,如此一來,若動畫腳本因為不明因素導致無法擷取時,依然可以繼續走下去不會成為 flow blocker。
Solution 2
影響外部資源截取的要素其實挺多,要面面俱到好似也不是那般容易,畢竟有些東西是控制在別人手裡,我們的任性不見得可以有效被解決。也因為這樣所以讓我思索著是否可以將這變數消滅。於是便想到一個邪魔歪道的解法,如果我可以…直接把動畫腳本 inline sign 進去的話,那麼不僅不用擔心 network / CORS 所帶來的影響,整體的 render performance 還能有效提升呢?!那麼 … 這有辦法實現嗎?
答案是肯定的,我相信很多朋友也都有使用過,我們可以透過 dataURI 將之具現化。一窺 MDN 文件可以知道 dataURI 的組成格式為:
data:[<media-type>][;base64],<data>
所以我們只要搞對 MIME Type,然後將動畫腳本 base64 encode,最後在依循上面的格式置入對應的位置中,便能完成了~
如果有設定 CSP 的朋友要記得針對 default-src 開放 data:,不然會被攔下來喔!
透過以上的邪魔歪道格式轉換後,便可以確保 Lottie 可以完整拿到動畫腳本了,自然就會正常 dispatch complete event 了。
Conclusion
有效結合過場動畫去銜接不同 flow 一直都是 web developers 101 的基本技能,希望透過上述與 Lottie 這些日子以來的相處過程分享能夠對大家有所助益。