Sublimetext.com 首頁的操作演示動畫不是 GIF,是在 canvas 中拼接圖片畫出來的,這是用什麼工具生成的?

前端同學看這張素材基本就能看出門道了,確實是罕見的實現方式,不可能是手工做的。

地址:http://www.sublimetext.com/


Sublime Text 的作者 Jon Skinner 剛發表了篇文章解釋為什麼要採取這樣的方式,以及如何實現的,地址在 http://www.sublimetext.com/~jps/animated_gifs_the_hard_way.html

實現方式大意是預先截取一系列 PNG 截屏圖片【每張為動畫的一幀】,然後將連續兩幀之間的細節區別計算出來(這部分是 Python 實現的),融合進一個整合後的 PNG 文件,同時生成一個對應的 JSON 格式元數據記錄如何從這張整合後的 PNG 文件裡面抽取每幀。最後在網頁上讀取整合的 PNG 文件和 JSON 元數據,通過 JavaScript 在 Canvas 元素里繪製動畫。對於不支持 Canvas 和 Video 標籤的老舊瀏覽器,則用 div 圖層疊加的方式模擬動畫。

之所以要這樣做是因為他想這個動畫在所有瀏覽器裡面都能播放,因此無法使用 Flash 【iOS 上無法播放】和 Video 標籤【IE6 無法播放】。GIF 動畫是一個可行的辦法,不過 GIF 格式限制只能顯示 256 色,畫面效果會大打折扣。所以作者就自己實現了這個姑且稱為 PNG 動畫的解決方案。此法的基本思想即視頻增量壓縮,對於每幀之間只有細小變化的 screencast 動畫來說效率非常高。

編碼器代碼已開源,在 https://github.com/sublimehq/anim_encoder 歡迎大家 fork。作者給出了如下幾個改進的建議:

  • 讓編碼器更友好:幫助文檔、壓縮速度過慢、對於源圖片 PNG 格式十分挑剔(比如不支持透明通道等)
  • 讓 JavaScript 播放器使用 requestAnimationFrame 方法。
  • 讓編碼器運行更快:特別是對於時長較長的動畫
  • 增量載入:目前在整個動畫完全載入之前不會有任何顯示,但因為第一幀總是在壓縮後的 PNG 文件的頭部,可以在等待載入的時候顯示第一幀作為占點陣圖。

此外,蘋果官方網站的 iPhone 5 展示頁面也採用了類似的思路,不過是針對 JPG 壓縮格式的圖片的,而且有簡單的用戶可操控的動畫支持,過程稍微複雜,詳見 https://docs.google.com/document/pub?id=1GWTMLjqQsQS45FWwqNG9ztQTdGF48hQYpjQHR_d1WsI 【Google Doc 連接,可能需要特殊方式才能訪問】


Sublime Text 的作者說他利用 Python 腳本把 png 圖片序列壓到一張 png 上,再利用 JavaScript + Canvas + PNG 表現在頁面上。

http://www.sublimetext.com/forum/viewtopic.php?f=2t=8164hilit=canvas

作者還說近期會寫 Blog 來詳細闡述這裡面用到的技術。

我想大概的流程是這樣的。

  1. 錄屏,把視頻轉為 png 圖片序列。
  2. Python 部分會比較相鄰兩幀之間的差異,把差異部分的位置,大小,差異出現幀的序號記錄下來,並把差異部分的矩形追加到合併的圖上,記錄其在合併後圖上的位置。
  3. JavaScript 把 Python 做的工作倒過來做就可以了,先放一張初始圖,播放時根據每幀的序號去合併的圖片上找對應的差異部分畫到 Canvas 的對應位置 就可以了。


忽然想起以前一個實時的像素重繪遊戲中的演算法里用了類似的增量刷新思路來提速。

如果改為基於圖片的bype級方法或許也能做成類似的效果。

不過,這種記差增量重現可能也就是在低幀多色上有獨特優勢。


推薦閱讀:

為什麼用ps作圖導出的gif比預覽的時候速度慢?
製作UI動態效果展示demo,如何輸出高質量小體積的GIF圖?
gif如何壓縮(每隔x幀取一幀再組合成gif)?
好看的gif圖哪裡找?

TAG:演示 | Canvas | GIF | SublimeText |