详解使用双缓存解决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 相关文章推荐
CSS3 :default伪类选择器使用简介
Mar 15 HTML / CSS
websocket+sockjs+stompjs详解及实例代码
Nov 30 HTML / CSS
canvas实现飞机打怪兽射击小游戏的示例代码
Jul 09 HTML / CSS
html5中监听canvas内部元素点击事件的三种方法
Apr 28 HTML / CSS
HTML5网页录音和上传到服务器支持PC、Android,支持IOS微信功能
Apr 26 HTML / CSS
突袭HTML5之Javascript API扩展5—其他扩展(应用缓存/服务端消息/桌面通知)
Jan 31 HTML / CSS
HTML5拖拽API经典实例详解
Apr 20 HTML / CSS
Canvas实现保存图片到本地的示例代码
Jun 28 HTML / CSS
canvas实现扭蛋机动画效果的示例代码
Oct 17 HTML / CSS
微信小程序canvas实现水平、垂直居中效果
Feb 05 HTML / CSS
HTML5给汉字加拼音收起展开组件的实现代码
Apr 08 HTML / CSS
Html5 webview元素定位工具的实现
Aug 07 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
linux下删除7天前日志的代码(php+shell)
2011/01/02 PHP
解析如何用php screw加密php源代码
2013/06/20 PHP
php实现用于删除整个目录的递归函数
2015/03/16 PHP
PHP 中使用ajax时一些常见错误总结整理
2017/02/27 PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
2017/04/18 PHP
Yii2中简单的场景使用介绍
2017/06/02 PHP
用js实现计算代码行数的简单方法附代码
2007/08/13 Javascript
node.js中的fs.lstatSync方法使用说明
2014/12/16 Javascript
用自定义图片代替原生checkbox实现全选,删除以及提交的方法
2016/10/18 Javascript
深入理解jQuery()方法的构建原理
2016/12/05 Javascript
微信小程序 解决请求服务器手机预览请求不到数据的方法
2017/01/04 Javascript
Bootstrap框架安装使用详解
2017/01/21 Javascript
详解nodejs异步I/O和事件循环
2017/06/07 NodeJs
AngularJS中重新加载当前路由页面的方法
2018/03/09 Javascript
微信小程序websocket实现聊天功能
2020/03/30 Javascript
vue js秒转天数小时分钟秒的实例代码
2018/08/08 Javascript
vue项目使用axios发送请求让ajax请求头部携带cookie的方法
2018/09/26 Javascript
详解微信小程序scroll-view横向滚动的实践踩坑及隐藏其滚动条的实现
2019/03/14 Javascript
vue+elementui实现点击table中的单元格触发事件--弹框
2020/07/18 Javascript
Python struct模块解析
2014/06/12 Python
Django Web开发中django-debug-toolbar的配置以及使用
2018/05/06 Python
python将一组数分成每3个一组的实例
2018/11/14 Python
利用python脚本如何简化jar操作命令
2019/02/24 Python
详解python和matlab的优势与区别
2019/06/28 Python
python 实现绘制整齐的表格
2019/11/18 Python
Python 去除字符串中指定字符串
2020/03/05 Python
Python自动登录QQ的实现示例
2020/08/28 Python
python使用bs4爬取boss直聘静态页面
2020/10/10 Python
HTML5在手机端实现视频全屏展示方法
2020/11/23 HTML / CSS
英国家庭和商业健身器材购物网站:Fitness Options
2018/07/05 全球购物
Ego Shoes官网:英国时髦鞋类品牌
2020/10/19 全球购物
简历的个人自我评价范文
2014/01/03 职场文书
培训专员岗位职责
2014/02/26 职场文书
就业协议书的作用
2014/04/11 职场文书
马丁路德金演讲稿
2014/05/19 职场文书
绿色校园广播稿
2014/10/13 职场文书