【H5动画】谈谈canvas动画的闪烁问题
一般来说,在H5开发中,使用canvas往往只是为了展示一些简单的图表或者简单短小的动画,很少考虑到有闪烁的问题。
最近,在手机QQ魔法表情的项目中,就遇到了奇葩的闪烁问题。
这里说的闪烁,是指动画刚开始播放,突然出现瞬间空白(大概1帧到2帧的时间)。
闪烁分析
这个魔法表情,实际是html5版本的动画,使用Fanvas(即将腾讯开源),从swf转化为canvas 2d动画。
在iOS体系下,无论哪个机型还是哪个系统版本,都没有出现问题。
但是,在部分Android机器上则出现了很奇葩的闪烁,包括小米note,小米4,三星,魅族。奇怪的是,小米同体系的红米note则完全正常。
翻阅H5 api的资料,我们知道requestAnimationFrame在Android 4.4后才支持,而动画的机制是,如果该接口不可用,则采用setInterval取代。
那么貌似有点眉目了,红米note也是4.4系统,而iOS全系都ok,也许问题就在这。
重温一下FPS和浏览器重绘的知识。浏览器保持一个帧频(一般60fps)刷新画面,这就包括页面中的canvas。而动画的绘制过程,包括几个步骤:
1、擦除整个canvas;
2、计算所有元件/图元的位置颜色;
3、逐个逐个,绘制所有元件到canvas上。
这个过程,由不精准的setInterval驱动,这个时钟无法跟浏览器重绘的频率同步。
那么,就可能出现这样的时序情况:
1、擦除整个canvas;
2、浏览器到达重绘时间点,此时canvas为空白,浏览器绘制空白的canvas;
3、50ms后,这一帧动画所有元件绘制完成(可能会因为动画复杂, 而消耗长时间,超过16ms)
关键点就在这里了。
好招不怕旧
双缓冲,只要对图形图象处理编程有稍稍一些了解,都应该听过这个术语,即使不知道这玩意是什么。这个技术非常非常古老,也非常非常简单,但效果却非常非常好。
来看看百度百科的说明,可能没有wikipedia专业,但我觉得足够解释问题了。
闪烁是图形编程的一个常见问题。需要多重复杂绘制操作的图形操作会导致呈现的图像闪烁或具有其他不可接受的外观。双缓冲的使用解决这些问题。双缓冲使用内存缓冲区来解决由多重绘制操作造成的闪烁问题。当启用双缓冲时,所有绘制操作首先呈现到内存缓冲区,而不是屏幕上的绘图图面。所有绘制操作完成后,内存缓冲区直接复制到与其关联的绘图图面。因为在屏幕上只执行一个图形操作,所以消除了由复杂绘制操作造成的图像闪烁。
回到我们的动画中,发现异曲同工,闪烁、掉帧的问题根源就是因为部分机型下没有自动实现cnavas的双缓冲(一般这些都是底层实现的),而canvas每一帧动画过程又比较漫长,擦除上一帧动画后,要过几十毫秒才能绘制完成下一帧,而这段时间内就会出现明显的空白。
解决办法就是:
创建一个临时canvas,先把下一帧动画绘制到临时canvas上。在每次真正绘制的时候,擦除正式canvas后,马上drawImage把临时canvas的内容copy过去,而这个copy过程是非常非常高效的,所以基本可以杜绝闪烁。
具体代码
p.update = function() {
if (!this.cacheCanvas) {
this.cacheCanvas = document.createElement("canvas");
this.cacheCanvas.width = this.canvas.width;
this.cacheCanvas.height = this.canvas.height;
} updateMovieClip(); //图形变换 var ctx = this.cacheCanvas.getContext("2d");
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.save();
ctx.clearRect(0, 0, this.canvas.width + 1, this.canvas.height + 1); //部分Android机器很奇葩,如果局部刷新会出现空白的情况
drawMovieclip(ctx); //绘制
ctx.restore(); //双缓冲,先画到临时canvas,再转到正式canvas
ctx = this.canvas.getContext("2d");
ctx.clearRect(0, 0, this.canvas.width + 1, this.canvas.height + 1);
ctx.drawImage(this.cacheCanvas, 0, 0, this.canvas.width, this.canvas.height); };
【H5动画】谈谈canvas动画的闪烁问题的更多相关文章
- HTML动画分类 HTML5动画 SVG库 SVG工具 Canvas动画工具
1.js配合传统css属性控制,可以使用setTimeout或者高级的requestAnimationFrame 2.css3 3.svg 4.canvas(当然,这个还是要配合js) 也许这么 ...
- 【30分钟学完】canvas动画|游戏基础(1):理论先行
前言 本文虽说是基础教程,但这是相对动画/游戏领域来说,在前端领域算是中级教程了,不适合前端小白或萌新.阅读前请确保自己对前端三大件(JavaScript+CSS+HTML)的基础已经十分熟悉,而且有 ...
- 2015.4.23 贪吃蛇、canvas动画,各种上传工具,url信息匹配以及最全前端面试题等
1.面向对象贪吃蛇 2.css中:hover 改变图片 页面加载完 第一次鼠标移入会闪一下 这是为啥? 解决方法:你把两张图合成一张图或者是先把图片加载到页面上,然后再hover出来. 解析:图片 ...
- 7 个顶级的 HTML5 Canvas 动画赏析
HTML5确实是一项改革浏览器乃至整个软件行业的新技术,它可以帮助我们Web开发者很方便地在网页上实现动画特效,而无需臃肿的Flash作为支撑.本文分享7个顶级的HTML5 Canvas 动画,都有非 ...
- 8个经典炫酷的HTML5 Canvas动画欣赏
HTML5非常强大,尤其是Canvas技术的应用,让HTML5几乎可以完成所有Flash能完成的效果.本文精选了8个经典炫酷的HTML5 Canvas动画欣赏,每一个都提供全部的源代码,希望对你有所帮 ...
- 7个惊艳的HTML5 Canvas动画效果及源码
HTML5非常强大,尤其是现在大部分浏览器都支持HTML5和CSS3,用HTML5制作的动画也多了起来.另外,Canvas上绘制图形非常简单,本文就分享了一些强大的HTML5 Cnavas动画,一起来 ...
- 《FLASH CC 2015 CANVAS 中文教程》——1、导出canvas动画,文件结构浅析
注::如果你对 FLASH 这个软件操作不够熟悉,建议你可以先看看FLASH动画之类的书. :FLASH CC 在文中直接简称为CC. :以下所以文章中所说的快捷键 如果你按了不起作用,请检查是否有其 ...
- Html5 Canvas动画旋转的小方块;
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- 【原创】测试不同浏览器播放canvas动画的平滑程度
Canvas无疑是HTML5开放式网络平台最激动人心的技术之一.目前,除了IE8以外,各类浏览器的新版本都支持HTML5 Canvas. 程序员需要通过Javascript调用Canvas API.基 ...
随机推荐
- 2017-2018-2 20155309 南皓芯 Exp5 MSF基础应用
实践内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 1.1一个主动攻击实践,如ms08_067; 1.2 一个针对浏览器的攻击,如ms11_05 ...
- Ext.js项目(二)
人事管理模块: 1.机构管理 2.部门管理 3.人员管理 一:用例图
- JS实现品字布局
在网页后台中常用的布局是头部+侧边栏的形式 为了省去多于代码和重复修改多个页面 头部和侧边栏都是共用的,一直不改变的,所以写死在页面中. 中间的内容根据点击而发生改变,所以用iframe包起来 如何实 ...
- 017 在SecureCRT中安装rz小工具
1.安装yum 2.上传本地的文件进虚拟机 3.注意点 只是属于SecureCRT的命令,同时,在上传的位置是现在所在的位置 4.测试
- Unity 之 Game视图不显示
如果你确认的Scene视图没有问题,试着检查一下 物体的Layer 与 camera的Culling mask是否一致,或者说camera的Culling mask中是否包含物体的layer 这是相机 ...
- 如何使用 Git LFS 提交大文件?
参考资料: An open source Git extension for versioning large files Git LFS的使用 如何使用 Git LFS 提交大文件? Git LFS ...
- PHP给图片加水印
<?php /** *图片加水印 *@param $srcImg 原图 *@param $waterImg 水印图片 *@param $savepath 保存路径 *@param $savena ...
- php手撸轻量级开发(一)
聊聊本文内容 之前讲过php简单的内容,但是原生永远是不够看的,这次用框架做一些功能性的事情. 但是公司用自己的框架不能拿出来,用了用一些流行的框架比如tp,larveral之类的感觉太重,CI也不顺 ...
- UltraEdit 不生成.bak文件
UE不自动生成.bak文件每次保存之后都能看到后面加个.bak后缀的文件出现有时真的很烦,而且还容易搞混,下面的方法可以解除这种烦恼.版本不同可以会有些差别. 中文版按照如下顺序设置:高级--> ...
- FTP 其他设置
参考文章 http://faichen.vip.blog.163.com/blog/static/37644066201010362051291/