详解使用双缓存解决Canvas clearRect引起的闪屏问题


Posted in HTML / CSS onApril 29, 2019

前言

今天用 canvas 做 H5 的时候遇到了闪屏问题。闪烁效果如下图:

详解使用双缓存解决Canvas clearRect引起的闪屏问题 

问题简介

功能简介

H5 该部分的功能为:通过点击二级菜单,切换图片的遮罩或者更换背景。

因为功能简单,所以用了原生 canvas 实现这个功能。但在使用 clearRect 清除画布的时候会出现闪烁的情况。

代码实现(问题代码)

以下代码即为出现闪屏的关键代码,省略了图片的定义与 onload:

// 点击二级菜单后,触发该函数更新画布
updateCanvas(){
    const canvas = document.getElementById('canvas'); // 获取画布
    const ctx = canvas.getContext('2d');
    ctx.clearRect(0,0,1448,750); // 清空画布
    // 开始重绘
    ctx.drawImage(bg,0,0); // 背景
    ... // 省略其他绘制过程
}

问题分析

经过简单分析,得出闪屏的原因是 clearRect 清除画布后,绘制的时间较长导致出现闪屏的现象。

什么是双缓存

来看一下microsoft 网站中双缓冲图形 这篇文章对双缓存的解释:

对图形进行编程时出现闪烁是一个常见问题。 需要多个复杂画图操作的图形操作可导致呈现的图像出现闪烁或具有不可接受的外观。 为解决这些问题,.NET Framework 提供了双缓冲功能。

双缓冲使用内容缓冲来解决与多个画图操作相关的闪烁问题。 启用双缓冲后,所有画图操作会首先呈现到内存缓冲而不是屏幕上的绘图图面。 所有画图操作完成后,内存缓冲会直接复制到与之关联的绘图图面。 由于屏幕上仅执行一个图形操作,因此与复杂画图操作相关的图像闪烁可得以消除。

使用双缓存解决问题

以上引用,简单来说,主要问题就是绘制时间较长导致了闪屏,解决方法就是新建一个 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
}

效果验收

可以很明显的看到闪屏问题解决了!

详解使用双缓存解决Canvas clearRect引起的闪屏问题 

总结

重绘画布的时候,我们需要使用 clearRect 来清空画布,此时的画布是空的,开始重绘后,如果内容较多,时间也就相应的增加,因此视觉出现了空档期,我们就看到了闪屏的情况;

解决闪屏,其实就是怎么解决绘制时间较长的问题;

这里参考了图形图象处理编程中 双缓存 的概念,将绘制过程交给了 缓存 canvas ,这样页面中的 canvas 就省去了绘制过程,而 缓存 canvas 并没有添加到页面,所以我们就看不到绘制过程,也就解决了闪屏的问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
移动端rem布局的两种实现方法
Jan 03 HTML / CSS
css 省略号 css3让多余的字符串消失并附加省略号的实现代码
Feb 07 HTML / CSS
css图标制作教程制作云图标
Jan 19 HTML / CSS
CSS中垂直居中的简单实现方法
Jul 06 HTML / CSS
基于Jquery和Css3代码制作可以缩放的搜索框
Nov 19 HTML / CSS
CSS3制作皮卡丘动画壁纸的示例
Nov 02 HTML / CSS
如何使用localstorage代替cookie实现跨域共享数据问题
Apr 18 HTML / CSS
canvas学习笔记之绘制简单路径
Jan 28 HTML / CSS
基于HTML5的齿轮动画特效
Feb 29 HTML / CSS
使用HTML5 Canvas绘制圆角矩形及相关的一些应用举例
Mar 22 HTML / CSS
Web前端页面跳转并取到值
Apr 24 HTML / CSS
HTML5高仿微信聊天、微信聊天表情|对话框|编辑器功能
Apr 23 HTML / CSS
浅谈HTML5新增和废弃的标签
Apr 28 #HTML / CSS
Canvas实现贝赛尔曲线轨迹动画的示例代码
Apr 25 #HTML / CSS
可能这些是你想要的H5软键盘兼容方案(小结)
Apr 23 #HTML / CSS
详解三种方式实现平滑滚动页面到顶部的功能
Apr 23 #HTML / CSS
小程序canvas中文字设置居中锚点
Apr 16 #HTML / CSS
用canvas做一个DVD待机动画的实现代码
Apr 12 #HTML / CSS
Html5适配iphoneX刘海屏的简单实现
Apr 09 #HTML / CSS
You might like
PHP Ajax实现页面无刷新发表评论
2007/01/02 PHP
PHP 采集程序中常用的函数
2009/12/09 PHP
php类声明和php类使用方法示例分享
2014/03/29 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
2015/11/15 PHP
PHP十六进制颜色随机生成器功能示例
2017/07/24 PHP
php curl发送请求实例方法
2019/08/01 PHP
javascript引用对象的方法
2007/01/11 Javascript
利用404错误页面实现UrlRewrite的实现代码
2008/08/20 Javascript
jQuery插件实现屏蔽单个元素使用户无法点击
2013/04/12 Javascript
使用jQuery清空file文件域的解决方案
2013/04/12 Javascript
js控制分页打印、打印分页示例
2014/02/08 Javascript
jQuery Mobile 触摸事件实例
2016/06/04 Javascript
jquery ajax结合thinkphp的getjson实现跨域的方法
2016/06/06 Javascript
浅谈angularJS中的事件
2016/07/12 Javascript
js时间比较 js计算时间差的简单实现方法
2016/08/26 Javascript
自制微信公众号一键排版工具
2016/09/22 Javascript
JavaScript中常用的验证reg
2016/10/13 Javascript
Spring Boot+AngularJS+BootStrap实现进度条示例代码
2017/03/02 Javascript
node.js中TCP Socket多进程间的消息推送示例详解
2018/07/10 Javascript
vue 实现cli3.0中使用proxy进行代理转发
2019/10/30 Javascript
python实现apahce网站日志分析示例
2014/04/02 Python
20个常用Python运维库和模块
2018/02/12 Python
Python实现基于PIL和tesseract的验证码识别功能示例
2018/07/11 Python
python无限生成不重复(字母,数字,字符)组合的方法
2018/12/04 Python
详解Python二维数组与三维数组切片的方法
2019/07/18 Python
python3 selenium自动化 下拉框定位的例子
2019/08/23 Python
Python进度条的制作代码实例
2019/08/31 Python
向领导表决心的话
2014/03/11 职场文书
升旗仪式演讲稿
2014/05/08 职场文书
“三支一扶”支教教师思想汇报
2014/09/13 职场文书
2014领导班子四风问题对照检查材料思想汇报
2014/09/21 职场文书
离婚协议书范文2014
2014/10/16 职场文书
小学教师工作总结2015
2015/04/07 职场文书
干部培训工作总结2015
2015/05/25 职场文书
2015年校务公开工作总结
2015/05/26 职场文书
创业计划书之川味火锅店
2019/09/02 职场文书