详解使用双缓存解决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 相关文章推荐
CSS中简写属性要注意TRouBLe的顺序问题(避免踩坑)
Mar 09 HTML / CSS
CSS3实现任意图片lowpoly动画效果实例
May 11 HTML / CSS
CSS3属性使网站设计增强同时不消弱可用性
Aug 29 HTML / CSS
CSS3实战第一波 让我们尽情的圆角吧
Aug 27 HTML / CSS
使用before和:after伪类制作css3圆形按钮
Apr 08 HTML / CSS
CSS3 Flex 弹性布局实例代码详解
Nov 01 HTML / CSS
详解css3中dispaly的Grid布局与Flex布局
Sep 11 HTML / CSS
HTML5安全介绍之内容安全策略(CSP)简介
Jul 10 HTML / CSS
html5的画布canvas——画出简单的矩形、三角形实例代码
Jun 09 HTML / CSS
HTML 5.1来了 9月份正式发布 更新内容预览
Apr 26 HTML / CSS
使用phonegap获取位置信息的实现方法
Mar 31 HTML / CSS
详解html5页面 rem 布局适配方法
Jan 12 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
memcached 和 mysql 主从环境下php开发代码详解
2010/05/16 PHP
PHPnow安装服务[apache_pn]失败的问题的解决方法
2010/09/10 PHP
php调用Google translate_tts api实现代码
2013/08/07 PHP
PHP异常类及异常处理操作实例详解
2018/12/19 PHP
js 可拖动列表实现代码
2011/12/13 Javascript
jQuery 三击事件实现代码
2013/09/11 Javascript
node.js中的console.info方法使用说明
2014/12/09 Javascript
JavaScript中解析JSON数据的三种方法
2015/07/03 Javascript
js实现常用排序算法
2016/08/09 Javascript
Move.js入门
2017/02/08 Javascript
Express框架之connect-flash详解
2017/05/31 Javascript
php简单数据库操作类的封装
2017/06/08 Javascript
基于rollup的组件库打包体积优化小结
2018/06/18 Javascript
JS桶排序的简单理解与实现方法示例
2019/11/25 Javascript
小程序实现图片移动缩放效果
2020/05/26 Javascript
vue cli3.0打包上线静态资源找不到路径的解决操作
2020/08/03 Javascript
[27:08]完美世界DOTA2联赛PWL S2 SZ vs Rebirth 第二场 11.21
2020/11/23 DOTA
用Python实现命令行闹钟脚本实例
2016/09/05 Python
python调用Delphi写的Dll代码示例
2017/12/05 Python
Python常见MongoDB数据库操作实例总结
2018/07/24 Python
win10下python3.8的PIL库安装过程
2020/06/08 Python
python实现批量转换图片为黑白
2020/06/16 Python
python 用opencv实现图像修复和图像金字塔
2020/11/27 Python
美国受信赖的教育产品供应商:Nest Learning
2018/06/14 全球购物
德国大型和小型家用电器网上商店:Energeto
2019/05/15 全球购物
Ellesse英国官网:意大利高级运动品牌
2019/07/23 全球购物
StudentUniverse英国:学生航班、酒店和旅游
2019/08/25 全球购物
个人简历中的自我评价范例
2013/10/29 职场文书
学校消防安全制度
2014/01/30 职场文书
公司营业员的自我评价
2014/03/04 职场文书
村委会换届选举方案
2014/05/03 职场文书
2015年教师节演讲稿范文
2015/03/19 职场文书
2015年资料员工作总结
2015/04/25 职场文书
励志语录:时光飞逝,请学会珍惜所有的人和事
2020/01/16 职场文书
go语言中http超时引发的事故解决
2021/06/02 Golang
CSS3实现指纹特效代码
2022/03/17 HTML / CSS