畫布是很熱門的做法 在畫面上繪製各種圖像,再做為 WebGL 的進入點。 可用來繪製形狀、圖片、執行動畫,甚至是顯示和處理影片內容。 經常用於在含有多媒體內容的網路應用程式中,提供美觀的使用者體驗。 線上遊戲。
此元件可編寫指令碼,也就是說,畫布上繪製的內容可透過程式建立。 例如 JavaScript這種畫布提供絕佳彈性。
同時,在現代網站上,指令碼執行頻率是 使用者回應問題的來源。 畫布邏輯和算繪作業是在與使用者互動相同的執行緒上進行, 動畫中涉及的運算 (有時會耗用大量資源) 可能會影響應用程式的 以及使用者感知的效能
幸運的是 OffscreenCanvas 回應該威脅
先前,畫布繪圖功能是與 <canvas>
元素綁定的。
也就是直接依附於 DOM顧名思義,
將 DOM 和 Canvas API 移至螢幕外,藉此分離該 DOM 和 Canvas API。
多虧有這種分離,「OffscreenCanvas」的算繪已經從 DOM 完全卸離, 因此速度比一般畫布稍有改善,因為網頁既沒有同步處理 兩者之間
另外,雖然在網路工作處理程序中,即使沒有 可使用 DOM。這可支援各種有趣的用途。
在工作站中使用 OffscreenCanvas
工作站 是網路的執行緒,可讓您在背景執行工作。
將部分指令碼移至工作站,可讓應用程式有更多執行重要使用者的工作空間 處理主執行緒的工作如果沒有 OffscreenCanvas,就無法在 worker 中使用 Canvas API 沒有可用的 DOM。
OffscreenCanvas 不會依賴 DOM,所以可以用。以下範例使用 OffscreenCanvas 計算 worker 中的漸層顏色:
// file: worker.js
function getGradientColor(percent) {
const canvas = new OffscreenCanvas(100, 1);
const ctx = canvas.getContext('2d');
const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
gradient.addColorStop(0, 'red');
gradient.addColorStop(1, 'blue');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, ctx.canvas.width, 1);
const imgd = ctx.getImageData(0, 0, ctx.canvas.width, 1);
const colors = imgd.data.slice(percent * 4, percent * 4 + 4);
return `rgba(${colors[0]}, ${colors[1]}, ${colors[2]}, ${colors[3]})`;
}
getGradientColor(40); // rgba(152, 0, 104, 255 )
解除封鎖主執行緒
將繁重計算作業移交給工作站 掌握主要執行緒上的重要資源使用 transferControlToOffscreen 方法將一般畫布鏡像到 OffscreenCanvas 執行個體。套用的作業對象 系統會自動在來源畫布上顯示 OffscreenCanvas。
const offscreen = document.querySelector('canvas').transferControlToOffscreen();
const worker = new Worker('myworkerurl.js');
worker.postMessage({canvas: offscreen}, [offscreen]);
在下列範例中,系統會在色彩主題變更時進行大量計算, 甚至還要花幾毫秒的時間你可以選擇在主執行緒上執行動畫 或在 worker 中在主要執行緒的情況下,您無法在重型執行緒的情況下與按鈕互動 工作正在執行中,但執行緒遭到封鎖。若是 worker,則不會影響 UI 回應速度。
其他做法也是如此:忙碌的主執行緒不會影響在上面的動畫 工作站您可以使用這項功能避免影像卡頓,並確保動畫流暢播放 即使主要執行緒流量仍不受影響,如以下範例所示
如果是一般畫布,當主要執行緒人為過勞時,動畫就會停止; 以工作站為基礎的 OffscreenCanvas 則流暢播放。
搭配熱門程式庫使用
由於 OffscreenCanvas API 通常與一般的 Canvas Element 相容,您可以 ,進一步改良產品,以及市面上一些主要的圖像庫。
例如,只要指定 以下為轉譯器建構函式中的畫布選項:
const canvasEl = document.querySelector('canvas');
const canvas =
'OffscreenCanvas' in window
? canvasEl.transferControlToOffscreen()
: canvasEl;
canvas.style = {width: 0, height: 0};
const renderer = new THREE.WebGLRenderer({canvas: canvas});
這裡的重點在於 Three.js 預期的畫布具有 style.width
和 style.height
屬性。
與 DOM 完全卸離的 OffscreenCanvas 沒有它,所以您需要自行提供
一種是直接練習
或是建立將這些值與
畫布尺寸
以下顯示如何在工作站中執行基本的 Three.js 動畫:
請注意,部分 DOM 相關 API 無法在 worker 中隨時使用, 如要使用紋理等更進階的 Three.js 功能,您可能需要更多替代方案。 如要瞭解如何開始實驗這些程式,請參閱 觀看 2017 年 Google I/O 大會的影片。
如要大量使用畫布的圖形功能,不妨考慮使用 OffscreenCanvas 影響應用程式效能讓工作人員能夠使用畫布轉譯背景內容 也更妥善地運用多核心系統。