App下載

在Canvas clearRect中引起的閃屏怎么解決?雙緩存解決閃屏問題詳解!

猿友 2021-08-03 11:05:41 瀏覽數(shù) (3938)
反饋

不知道大家有沒有這樣的經(jīng)歷,就是在打開手機軟件或者其他的應(yīng)用時候手機會突然的出現(xiàn)閃屏的效果,這時候我們一般會以為是手機壞了,其實不是這個是由于我們的程序的問題,那么今天小編就和大家分享有關(guān)于:“ 在Canvas clearRect中引起的閃屏怎么解決? ”這個問題,下面是小編整理的相關(guān)內(nèi)容,大家可以作為學(xué)習(xí)參考!

前言

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

 

問題簡介

功能簡介

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

因為功能簡單,所以用了原生 canvas 實現(xiàn)這個功能。但在使用 clearRect 清除畫布的時候會出現(xiàn)閃爍的情況。

代碼實現(xiàn)(問題代碼)

以下代碼即為出現(xiàn)閃屏的關(guān)鍵代碼,省略了圖片的定義與 onload:

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

問題分析

經(jīng)過簡單分析,得出閃屏的原因是 clearRect 清除畫布后,繪制的時間較長導(dǎo)致出現(xiàn)閃屏的現(xiàn)象。

什么是雙緩存

來看一下microsoft 網(wǎng)站中雙緩沖圖形 這篇文章對雙緩存的解釋:

對圖形進行編程時出現(xiàn)閃爍是一個常見問題。 需要多個復(fù)雜畫圖操作的圖形操作可導(dǎo)致呈現(xiàn)的圖像出現(xiàn)閃爍或具有不可接受的外觀。 為解決這些問題,.NET Framework 提供了雙緩沖功能。

雙緩沖使用內(nèi)容緩沖來解決與多個畫圖操作相關(guān)的閃爍問題。 啟用雙緩沖后,所有畫圖操作會首先呈現(xiàn)到內(nèi)存緩沖而不是屏幕上的繪圖圖面。 所有畫圖操作完成后,內(nèi)存緩沖會直接復(fù)制到與之關(guān)聯(lián)的繪圖圖面。 由于屏幕上僅執(zhí)行一個圖形操作,因此與復(fù)雜畫圖操作相關(guān)的圖像閃爍可得以消除。

使用雙緩存解決問題

以上引用,簡單來說,主要問題就是繪制時間較長導(dǎo)致了閃屏,解決方法就是新建一個 canvas 作為 緩存 canvas ,通過 緩存 canvas 完成繪制過程,繪制完成后,直接將 緩存 canvas 復(fù)制到原來的 canvas,這樣就可以解決繪制時間過長導(dǎo)致的閃屏問題。

代碼實現(xiàn)

以下代碼即為關(guān)鍵代碼,省略了圖片的定義與 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; // 設(shè)置寬高

    // 開始繪制
    tempCtx.drawImage(bg,0,0); // 背景
    ... // 省略其他繪制過程
    
    // 緩存 canvas 繪制完成
    
    ctx.clearRect(0,0,1448,750); // 清空舊 canvas
    ctx.drawImage(tempCanvas,0,0); // 將緩存 canvas 復(fù)制到舊的 canvas
}

效果驗收

可以很明顯的看到閃屏問題解決了!

 

總結(jié)

重繪畫布的時候,我們需要使用 clearRect 來清空畫布,此時的畫布是空的,開始重繪后,如果內(nèi)容較多,時間也就相應(yīng)的增加,因此視覺出現(xiàn)了空檔期,我們就看到了閃屏的情況;

解決閃屏,其實就是怎么解決繪制時間較長的問題;

這里參考了圖形圖象處理編程中 雙緩存 的概念,將繪制過程交給了 緩存 canvas ,這樣頁面中的 canvas 就省去了繪制過程,而 緩存 canvas 并沒有添加到頁面,所以我們就看不到繪制過程,也就解決了閃屏的問題。

那么以上就是有關(guān)于:“在Canvas clearRect中引起的閃屏怎么解決?”這個問題的相關(guān)內(nèi)容分享,當然如果你有其他更好的方法也可以和大家一同分享你的解決方法一同學(xué)習(xí)成長,有喜歡html5這方面的小伙伴們可以在W3Cschool中進行學(xué)習(xí)和深造。


0 人點贊