详解双缓冲绘图机制 HTML5-canvas绘图黑屏白屏解决方案( 二 )


经过了这样的优化之后 , 一般的图形都不会在出现HTML5-黑屏的现象了 。

详解双缓冲绘图机制  HTML5-canvas绘图黑屏白屏解决方案

文章插图
·白屏
说完了黑屏 , 接下来说说白屏 。
先简单阐述一下为什么会产生白屏 。首先可以肯定的是:白屏一定是程序有问题!最常见的情况:
(1)绘图代码报错 , 导致绘图不执行 , 因此出现白屏
(2)计算图形坐标的时候算错 , 比如计算出无穷大或者或者超出画布边界的坐标值 , 导致你画的图看不见(HTML5-在执行绘图方法时传入的数据异常时不会抛出任何错误) , 也是白屏 。
(3)没有给画布设置width或或值为0 , 比如画布初始化的时候页面还没有撑开 , 导致画布元素的高度或者宽度为零 , 也会出现白屏 。
(4)如果看到这里仍然没有解决你的白屏问题 , 那么恭喜你 , 本文将帮助你解决“动画白屏闪烁”问题 。首先简单说下什么是“动画白屏闪烁” 。
做过H5-动画的读者肯定知道动画制作的基本原理:
1.将画布清空
2.计算下一帧图形并绘制
3.空出一帧的时间(通常为16ms)
4.循环第一步
我们用一个简单的线条变长的动画代码为示例 , 进一步说明这四步动画过程:
//获取页面中的canvas画布容器 , 通常为一个divvar container=document.getElementById("container");//创建一个真实的画布 , 他将呈现给用户var realCanvas=document.createElement("canvas");//设置realCanvas的width/height属性 , 乘以二以防止像素点模糊问题realCanvas.width=container.clientWidth*2;realCanvas.height=container.clientHeight*2;//设置realCanvas的样式width/height属性 , 填充满父元素realCanvas.style.width=container.clientWidth+"px";realCanvas.style.height=container.clientHeight+"px";container.appendChild(realCanvas);/*-------------------初始化--------------------*///开始绘制var realContext=realCanvas.getContext("2d");//初始化线条长度 , 这个长度将会随着动画演进而变长var lineHeight=0,//设置动画帧间隔为16毫秒tick=16;//使用setTimeout定时器保证动画帧间隔相同setTimeout(function animate(){//步骤一realContext.clearRect(0,0,realCanvas.width,realCanvas.height);//步骤二lineHeight++;//步骤三realContext.moveTo(10,10);realContext.lineTo(10,lineHeight);//步骤四 , 在下一个定时器中调用内联函数 , 从而创造出流畅的动画setTimeout(animate,tick);},tick);
详解双缓冲绘图机制  HTML5-canvas绘图黑屏白屏解决方案

文章插图
用一个图形来形象的表示这段代码的过程:
详解双缓冲绘图机制  HTML5-canvas绘图黑屏白屏解决方案

文章插图
这幅图表示了我们用普通动画代码实现方案时程序执行的过程 , 首先设置了帧间隔16毫秒 , 我们在中使用定时器”“方法来每个16毫秒执行一次动画绘图;然后当方法开始执行时 , 我们擦除上一帧的图像(清空画布);接着计算下一帧图像的坐标点;最终绘制新的图像 , 然后下一帧循环往复 , 形成了流畅的动画 。很多细心的读者应该已经发现了 , 当我们要绘制时 , 先执行了擦除 , 再来计算图形以及绘制 , 那么计算图形这段时间画布不就会显示“空白” 。在前文提供的例子里大家永远不会看到画布空白 , 因为计算线条图形的时间太短了(小于10纳秒) , 但是当我们绘制的动画图形足够复杂时 , 在某些计算能力不足的设备的浏览器上就会看到“动画白屏闪烁” 。双缓冲绘图技术同样可以巧妙的解决这个问题 。