專為網路建構的觸控筆繪圖應用程式長期以來,一直受到延遲問題造成的困擾,因為網頁必須同步處理圖形更新與 DOM。在任何繪圖應用程式中,超過 50 毫秒的延遲時間可能會幹擾使用者的手眼協調,導致應用程式難以使用。
canvas.getContext()
的 desynchronized
提示叫用了可略過一般 DOM 更新機制的不同程式碼路徑。而是指示基礎系統盡可能略過組合,在某些情況下,畫布的基礎緩衝區會直接傳送至螢幕的顯示控制器。這樣可以消除使用轉譯器合成器佇列所造成的延遲時間。
評價如何?
如要查看驗證碼,請向下捲動。如要查看實際運作情形,您需要一部配備觸控螢幕的裝置,而且最好使用觸控筆。(手指也能使用)。如有,請嘗試使用 2d 或 webgl 範例。至於其他部分,請觀看Miguel Casas 提供的示範影片,這是實作這項功能的工程師之一。開啟試用版並按下播放按鈕 然後隨機快速地來回移動滑桿
這個範例使用《Blender (Blender) 開放式電影專案 Durian 的 Durian 這個短片 Sintel 的 1 分 21 秒片段。在此範例中,電影透過 <video>
元素播放,該元素的內容同時轉譯至 <canvas>
元素。許多裝置都能在不造成乾擾的情況下執行這個作業,但例如 ChromeOS 這類具有前緩衝區轉譯的裝置可能有撕裂。(這部電影很棒,卻讓人感到心碎。
我看到它後一小時了沒用。請考慮自己警告)。
使用提示
相較於將 desynchronized
新增至 canvas.getContext()
,使用低延遲的做法更勝一籌。我會一一逐一探討問題。
建立畫布
在另一個 API 上,我會先討論功能偵測。如果是 desynchronized
提示,您必須先建立畫布。呼叫 canvas.getContext()
,然後傳遞新的 desynchronized
提示,並將值設為 true
。
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('2d', {
desynchronized: true,
// Other options. See below.
});
功能偵測
接著,請呼叫 getContextAttributes()
。如果傳回的屬性物件含有 desynchronized
屬性,請進行測試。
if (ctx.getContextAttributes().desynchronized) {
console.log('Low latency canvas supported. Yay!');
} else {
console.log('Low latency canvas not supported. Boo!');
}
避免閃爍
如果未正確程式碼,在兩種情況下可能會造成閃爍。
部分瀏覽器 (包括 Chrome 在內) 可在影格之間清除 WebGL 畫布。螢幕控制器可以在緩衝區空白的情況下讀取緩衝區,導致圖片繪圖閃爍。如要避免這種情況,請將 preserveDrawingBuffer
設為 true
。
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('webgl', {
desynchronized: true,
preserveDrawingBuffer: true
});
如果在自己的繪圖程式碼中清除畫面內容,也可能會發生閃爍情形。如果一定要清除,請繪製至螢幕外 framebuffer,然後複製到螢幕上。
Alpha 版
即使 Alpha 設為 true,半透明畫布元素仍可取消同步處理,但上方不得含有任何其他 DOM 元素。
只能有一個
首次呼叫 canvas.getContext()
後,即無法變更結構定義屬性。一直都是這樣,但如果重複閱讀,您就不會覺得有困難或忘記了。
舉例來說,假設我取得結構定義並將 Alpha 值指定為 false,隨後在程式碼中再次呼叫 canvas.getContext()
,並將 Alpha 設為 true,如下所示。
const canvas = document.querySelector('myCanvas');
const ctx1 = canvas.getContext('2d', {
alpha: false,
desynchronized: true,
});
//Some time later, in another corner of code.
const ctx2 = canvas.getContext('2d', {
alpha: true,
desynchronized: true,
});
ctx1
和 ctx2
是同一個物件,但並不明顯。Alpha 仍為 false,且系統一律不會建立 Alpha 等於 true 的結構定義。
支援的畫布類型
傳遞至 getContext()
的第一個參數是 contextType
。如果您很熟悉 getContext()
,那麼您應該想知道除了「2d」的結構定義類型外,是否還有其他支援類型。下表列出支援 desynchronized
的結構定義類型。
contextType | 情境類型物件 |
---|---|
|
|
|
|
|
|