使用雙緩存解決 Canvas clearRect 引發的閃屏問題

前言

今天用 canvas 作 H5 的時候遇到了閃屏問題。閃爍效果以下圖:javascript

問題簡介

功能簡介

H5 該部分的功能爲:經過點擊二級菜單,切換圖片的遮罩或者更換背景。html

由於功能簡單,因此用了原生 canvas 實現這個功能。但在使用 clearRect 清除畫布的時候會出現閃爍的狀況。java

代碼實現(問題代碼)

如下代碼即爲出現閃屏的關鍵代碼,省略了圖片的定義與 onload:git

// 點擊二級菜單後,觸發該函數更新畫布
updateCanvas(){
    const canvas = document.getElementById('canvas'); // 獲取畫布
    const ctx = canvas.getContext('2d');
    ctx.clearRect(0,0,1448,750); // 清空畫布
    // 開始重繪
    ctx.drawImage(bg,0,0); // 背景
    ... // 省略其餘繪製過程
}
複製代碼

問題分析

通過簡單分析,得出閃屏的緣由是 clearRect 清除畫布後,繪製的時間較長致使出現閃屏的現象。github

什麼是雙緩存

來看一下 microsoft 網站中 雙緩衝圖形 這篇文章對雙緩存的解釋:編程

對圖形進行編程時出現閃爍是一個常見問題。 須要多個複雜畫圖操做的圖形操做可致使呈現的圖像出現閃爍或具備不可接受的外觀。 爲解決這些問題,.NET Framework 提供了雙緩衝功能。canvas

雙緩衝使用內容緩衝來解決與多個畫圖操做相關的閃爍問題。 啓用雙緩衝後,全部畫圖操做會首先呈現到內存緩衝而不是屏幕上的繪圖圖面。 全部畫圖操做完成後,內存緩衝會直接複製到與之關聯的繪圖圖面。 因爲屏幕上僅執行一個圖形操做,所以與複雜畫圖操做相關的圖像閃爍可得以消除。緩存

使用雙緩存解決問題

以上引用,簡單來講,主要問題就是繪製時間較長致使了閃屏,解決方法就是新建一個 canvas 做爲 緩存 canvas,經過 緩存 canvas 完成繪製過程,繪製完成後,直接將 緩存 canvas 複製到原來的 canvas,這樣就能夠解決繪製時間過長致使的閃屏問題。函數

代碼實現

如下代碼即爲關鍵代碼,省略了圖片的定義與 onload:動畫

updateCanvas(){
    const canvas = document.getElementById('canvas'); // 獲取頁面中的 canvas
    const ctx = canvas.getContext('2d');
    
    const tempCanvas = document.createElement('canvas'); // 新建一個 canvas 做爲緩存 canvas
    const tempCtx = tempCanvas.getContext('2d');
    tempCanvas.width = 1448; tempCanvas.height = 750; // 設置寬高

    // 開始繪製
    tempCtx.drawImage(bg,0,0); // 背景
    ... // 省略其餘繪製過程
    
    // 緩存 canvas 繪製完成
    
    ctx.clearRect(0,0,1448,750); // 清空舊 canvas
    ctx.drawImage(tempCanvas,0,0); // 將緩存 canvas 複製到舊的 canvas
}
複製代碼

效果驗收

能夠很明顯的看到閃屏問題解決了!

總結

  • 重繪畫布的時候,咱們須要使用 clearRect 來清空畫布,此時的畫布是空的,開始重繪後,若是內容較多,時間也就相應的增長,所以視覺出現了空檔期,咱們就看到了閃屏的狀況;
  • 解決閃屏,其實就是怎麼解決繪製時間較長的問題;
  • 這裏參考了圖形圖象處理編程中 雙緩存 的概念,將繪製過程交給了 緩存 canvas,這樣頁面中的 canvas 就省去了繪製過程,而 緩存 canvas 並無添加到頁面,因此咱們就看不到繪製過程,也就解決了閃屏的問題。

參考連接

更多文章

相關文章
相關標籤/搜索