對SVG動畫進行惰性異步光柵化處理

翻譯:瘋狂的技術宅
原文: http://jakearchibald.com/2017...

本文首發微信公衆號:jingchengyideng
歡迎關注,天天都給你推送新鮮的前端技術文章javascript


渲染SVG圖像可能會很是慢

在轉換 SVG 圖像時,瀏覽器會試着在每一幀上進行渲染,以便使圖像儘量的清晰。 不幸的是,SVG渲染可能會很慢,特別是對於較大的圖像。前端

這裏是一個DEMO,打開後點擊「Scale SVG」查看效果。java

圖:使用 Devtools 查看SVG動畫的時間線

圖:使用 Devtools 查看SVG動畫的時間線git

這是一個很是複雜的SVG,在某些幀上消耗的時間是咱們幀預算的10倍,因此這個動畫看起來很是糟糕。 這是在一款功能強大的MacBook上作的測試。github

若是是更簡單的SVG,就不那麼糟了。 這是用Firefox的logo演示的另外一個例子,看起來效果還能夠。web

不過新API爲咱們提供了更多的控制方法:chrome

SVG柵格化的惰性處理

createImageBitmap(imgElement).then(imageBitmap => { 
  // … 
});

createImageBitmap能夠將許多不一樣的圖像柵格化爲位圖數據,這些數據能夠繪製到canvas元素上。 可是,在Chrome 61+中,啓用了chrome://flags/#enable-experimental-canvas-features,它能夠爲 SVG 圖像啓用HTML圖像元素,並在主線程以外進行異步的柵格化處理,因此不會破壞動畫。canvas

另外你還能夠只渲染SVG的一部分,並以特定大小進行輸出:瀏覽器

createImageBitmap( 
  imgElement, 
  sourceCropX, sourceCropY, 
  sourceCropWidth, sourceCropHeight, 
  {resizeWidth, resizeHeight} 
).then(imageBitmap => …);

這容許咱們很是方便的使用畫布對SVG進行位圖縮放,同時渲染被裁剪後且很是清晰的版本。 一旦清晰版準備就緒,就能夠將其包含在動畫中。微信

這裏是一個DEMO,按「Scale canvas」查看效果。 須要Chrome 61+ 中查看,並啓用 chrome://flags/#enable-experimental-canvas-features

img

圖:Devtools中畫布動畫的時間線

使用這種方法對CPU來講更加友好,動畫也很流暢:

查看SVG動畫與SVG-in-canvas兩種效果比較的視頻演示:https://youtu.be/-yQBbWlXuqg

對於複雜的汽車SVG圖像,最後纔會出現清晰的圖像。 使用Firefox徽標時,清晰版出現得更早,由於渲染時間更短。

DEMO的全部代碼:https://glitch.com/edit/#!/sv...:1:0

平滑光柵化

從上面的時間線能夠看出,Chrome在將更清晰的紋理傳到GPU時仍然會跳過一幀。 這個問題能夠經過將工做分塊爲更小的塊來解決,所以GPU上傳不會破壞幀預算。

OpenSeadragon:能夠動態加載圖像切片,並建立可縮放圖像。 它很是適合從網絡中獲取位圖數據,但有點hack。

Zoomable lazy-rendered tiled SVG: 須要Chrome 61+並啓用 chrome://flags/#enable-experimental-canvas-features

是的,邊緣有一點粗糙。 就像我前面說的那樣,這是一個hack。 不過我真的對此很興奮,對 SVG 圖像更加酷炫的處理技術在逐漸用於web。


本文首發微信公衆號:jingchengyideng

歡迎掃描二維碼關注公衆號,天天推送我翻譯的技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

相關文章
相關標籤/搜索