zoukankan      html  css  js  c++  java
  • HTML5 Canvas核心技术—图形、动画与游戏开发.pdf7

    性能

    运行putImageData()比drawImage()慢,同等条件下优先考虑drawImage()

    操作图像数据需要遍历大量数据,应该注意几点:

    1)避免在循环体中直接访问对象属性,应当保存在局部变量中

    2)应该用循环计数器遍历完整的像素,而非像素分量(每4个一组)

    3)逆向遍历与移位技巧效果并不好

    4)不要频繁使用getImagedata()

    视频处理

    var video=document.getElementById('video');  //A <video>element

      ...

    context.drawImage(video,0,0);  //取其中某一帧

    视频格式

    以上三种格式并不是所有浏览器都支持,需要指定多钟格式的文件,在video元素中嵌入source元素

    <video>

      <source src='video.ogg'>

      <source src='video.mp4'>

    </video>

    在Canvas中播放视频

    把一段<video>元素display设置为none,将视频的每一帧绘制到canvas上

    第5章 动画

    动画循环:持续更新并重绘就叫做“动画循环”,它是所有动画的核心逻辑

    死循环:

    function animate(){...}

    while(true){animate();}

    要实现动画效果,必须让浏览器没隔一段时间就有一个喘息的机会

    不要使用window.setInterval()或window.setTimeout()方法来做动画,这两个方法并不能提供精确计时机制,浏览器有个术语“clamping the timeout interval(强制规定时间间隔的下限)”,并且不应该主动命令浏览器何时去绘制下一帧(浏览器有自己的动画机制),应该由浏览器来通知你,总结:

    都是通用方法,并不是专为制作动画而用

    达不到毫秒的精确度

    没有对动画的优化

    不考虑绘制动画的最佳时机

    HTML5有一个requestAnimationFrame()方法,想要播放动画时就调用requestAnimationFrame()方法,并将指向动画播放函数的引用传递给它,浏览器决定绘制第一帧动画时,就调用这个函数,根据情况可再次调用,使动画持续下去

    function(time){

        requestAnimationFrame(animate);

      }

    requestAnimationFrame(animate);

    调用requestAnimationFrame()方法时,不必指定定帧速率,浏览器会自动选择合适的帧速率

    W3C也提供了cancelRequestAnimationFrame()方法,用于取消回调函数,requestAnimationFrame()方法返回一个long型的对象,用作标识回调函数身份的句柄(相当于setInterval函数返回的句柄),若要取消,传递给cancelRequestAnimationFrame()即可

    requestAnimationFrame()方法在回调动画函数时,会传递给它一个时间值,表示1970年1月1日到当前所经过的毫秒数

    可移植与各浏览器平台的动画循环逻辑:如果发现当前浏览器支持W3C标准方法,就使用它,否则使用浏览器专有实现方式,如果两者都不支持,只能借助setTimeout()方法来实现

    帧速率的计算,动画每秒播放的帧数(fps)计算每一帧动画当前的时间,获取时间差,1000毫秒除时间差

    以不同的帧速率来执行各种任务(分数等更新速率不必与动画速率相同)

    恢复动画背景,处理背景有三种办法

    1)所有内容都擦除,并重新绘制

    2)仅重绘内容发生变化的那部分区域

    3)从离屏缓冲区中将内容发生变化的那部分背景图像复制到屏幕上

    如果背景很简单,把每帧动画的所有内容都重绘一遍反而可以获得最佳性能

    利用剪辑区域处理动画背景

    所有的绘制操作都限定在某条路径所定义的范围内,利用剪辑区域技术来恢复上一帧动画占据的背景,有时可以提高绘制速度

    1)调用context.save(),保存屏幕的canvas的状态

    2)通过调用beginPath()来开始一段新的路径

    3)在context对象上调用arc()、rect()来设置路径

    4)调用context.clip()方法,将当前路径设置为屏幕canvas的剪辑区域

    5)擦除屏幕canvas中的图像

    6)将背景图像绘制到屏幕canvas中

    7)恢复屏幕canvas的状态参数

    利用图块复制技术来处理动画背景

    将所有的背景绘制到离屏canvas上,再将背景图块复制到屏幕上

    一般来说通过图块复制比剪辑区域速度更快,但离屏canvas更占用内存

    利用双缓冲技术绘制动画(浏览器自动使用该技术,手工实现反而降低性能)

    清除canvas然后绘制下一帧动画,如果动画是单缓冲,意味着其内容会被立即绘制到屏幕,擦除背景的一瞬间所造成闪烁

    防止闪烁可以使用双缓冲,即将所有东西绘制到离屏canvas上,再将离屏canvas中的图片一次性复制到屏幕canvas中

    基于时间的运动

    底层的帧速率不应该影响动画的帧速率,动画帧速率应该保持稳定

    背景的滚动

    视差动画:让各个动画图层以不同的速度滚动,产生视差效果

    用户手势

    定时动画:很多动画需要在某个时间段内运行

    动画制作得而最佳指导原则

    使用类似requestNextAnimationFrame()这样的“polyfill式”方法来保持浏览器兼容性

    将业务逻辑的更新与动画的绘制分开

    使用“基于时间的运动”来协调动画的播放速度

    用剪辑区域或图块复制技术将复杂的背景图像恢复到屏幕上

    必要时可以使用一个或者多个离屏缓冲区提升背景的绘制速度

    不要手工实现传统的双缓冲算法,浏览器会自动实现它

    不要通过CSS指定阴影及圆角效果

    不要在Canvas中进行带有阴影效果的绘制操作

    不要在播放动画时分配内存

    使用性能调试及时间轴工具来监控并改善动画的绘制效率

  • 相关阅读:
    Hibernate_条件查询客户列表
    Hibernate_添加联系人练习
    Linux目录的切换
    CentOS6.5在VMware中安装
    一个关于vue+mysql+express的全栈项目(三)------ 登录注册功能的实现(已经密码安全的设计)
    一个关于vue+mysql+express的全栈项目(二)------ 前端构建
    基于vue实现模糊匹配(这里以邮箱模糊匹配为例,其他的模糊匹配都可以类比)
    一个关于vue+mysql+express的全栈项目(一)
    关于Google浏览器Unable to preventDefault inside passive event listener due to target being treated as passive.的解决方案
    在移动端H5开发中(关于安卓端position:fixed和position:absolute;和虚拟键盘冲突的问题,以及解决方案)
  • 原文地址:https://www.cnblogs.com/sdgjytu/p/3905475.html
Copyright © 2011-2022 走看看