zoukankan      html  css  js  c++  java
  • 动画概念和实现介绍

     

    动画是指由许多帧静止的画面,以一定的速度(如每秒16张)连续播放时,肉眼因视觉残象产生错觉,而误以为画面活动的作品。——维基百科

    超人大战赛亚人

    几个基本概念

    简单介绍几个关于动画的基本概念。

    帧:在动画过程中,每一幅静止画面即为一"帧";

    帧率:即每秒钟播放的静止画面的数量,单位是fps(Frame per second)或赫兹(Hz);

    帧时长:即每一幅静止画面的停留时间,单位一般是ms(毫秒);

    丢帧:在帧率固定的动画中,某一帧的时长远高于平均帧时长,导致其后续数帧被挤压而丢失的现象;

    我们在显示器上看到的动画,每一帧变化都是系统绘制出来的(GPU或者CPU)。它的最高绘制频率受限于显示器的刷新频率(而非显卡,大多数是60Hz或者75Hz)。

    帧频越高,屏幕上图片闪烁感就越小,稳定性也就越高。人的眼睛不容易察觉75Hz以上刷新频率带来的闪烁感。

     

    动画库合理使用:

    最好不要引用动画库,会造成性能问题,可能频繁的访问dom,可以原生实现的尽量用原生的

    避免使用 JavaScript 动画库。只有在使用常规的 CSS 转换和动画完全无法实现时,才去使用这些库。

    即使这些 JavaScript 动画库使用 CSS 转换,合成属性和 requestAnimationFrame( ),但是它们仍然运行在 JavaScript 的主线程上。基本上这些库会使用内联样式每16ms访问一次 DOM。你需要确保所有的 JavaScript 都在每帧8ms以内完成,才能保持动画的平滑性。

    另一方面,CSS 动画和转换会在主线程中运行,如果能够高效执行,则能避免重新布局/重排的情况出现。

    考虑到大多数动画都在加载或用户交互的过程中运行,这可以为你的 web 应用程序提供非常重要的调整空间。

    web Animations API 是一个即将到来的功能集,它能够脱离主线程执行高性能的 JavaScript 动画。但就目前而言,还需要继续使用 CSS 转换等技术

    实现方式

    通常我们在前端实现动画效果的几种主要实现方式如下:

    JavaScript:通过定时器(setTimeout 和 setIterval)来间隔来改变元素样式,或者使用requestAnimationFrame;

    CSS3:transition 和 animation;

    HTML5:使用HTML5提供的绘图方式(canvas、svg、webgl);

     

    requestAnimationFrame

    requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘

    设置这个API的目的是为了让各种网页动画效果(DOM动画、Canvas动画、SVG动画、WebGL动画)能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。代码中使用这个API,就是告诉浏览器希望执行一个动画,让浏览器在下一个动画帧安排一次网页重绘。

    requestAnimationFrame使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用,由于功效只是一次性的,所以想实现连续的动效,需要递归调用,示例如下:

    <div id="demo" style="position:absolute; 100px; height:100px; background:#ccc; left:0; top:0;"></div> 
       
    <script>
    var demo = document.getElementById('demo'); 
    function render(){ 
        demo.style.left = parseInt(demo.style.left) + 1 + 'px'; //每一帧向右移动1px 
    }
    requestAnimationFrame(function(){ 
        render(); 
        //当超过300px后才停止 
        if(parseInt(demo.style.left) <= 300) requestAnimationFrame(arguments.callee); 
    });
    </script>

    cancelAnimationFrame方法用于取消重绘:

    var requestID = requestAnimationFrame(repeatOften); 
    cancelAnimationFrame(requestID); 

    使用requestAnimationFrameAPI的优势如下:

    会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随显示器的刷新频率(60 Hz或者75 Hz);

    在隐藏或不可见的元素中,将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量;

     

    目前,主要浏览器Firefox 23 / IE 10 / Chrome / Safari)都支持这个方法。可以用下面的方法,检查浏览器是否支持这个API。如果不支持,则自行模拟部署该方法。

    window.requestAnimFrame = (function(){ 
      return  window.requestAnimationFrame || 
              window.webkitRequestAnimationFrame || 
              window.mozRequestAnimationFrame || 
              window.oRequestAnimationFrame || 
              window.msRequestAnimationFrame || 
              function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element){ 
                window.setTimeout(callback, 1000 / 60); 
              }; 
    })();

    所以,可以这么说,requestAnimationFrame就是一个性能优化版、专为动画量身打造的setTimeout,不同的是requestAnimationFrame不是自己指定回调函数运行的时间,而是跟着浏览器内建的刷新频率来执行回调,这当然就能达到浏览器所能实现动画的最佳效果了。

    DEMO传送门:https://jsfiddle.net/gaogy/wwaejvLn/

     

    Transition

    CSS 中的 transition 属性允许块级元素中的属性在指定的时间内平滑的改变,简单看下其语法规则:

    transition: property duration timing-function delay;

    具体属性值介绍如下:

     

    DEMO传送门:http://www.w3school.com.cn/tiy/t.asp?f=css3_transition

    Animation

    类似的CSS还提供了一个Animation属性,不过区别于Transition,Animation作用于元素本身而不是样式属性,可以使用关键帧的概念,应该说可以实现更自由的动画效果。

    语法

    具体属性值介绍如下:

    DEMO传送门:http://www.w3school.com.cn/tiy/t.asp?f=css3_animation

    Canvas

    <canvas>是HTML5新增的元素,作为页面图形绘制的容器,可用于通过使用JavaScript中的脚本来绘制图形。例如,它可以用于绘制图形,制作照片,创建动画,甚至可以进行实时视频处理或渲染,Canvas具有如下特点:

    • 依赖分辨率,基于位图;
    • 不支持事件处理器;
    • 弱的文本渲染能力;
    • 能够以 .png 或 .jpg 格式保存结果图像;
    • 最适合图像密集型的游戏,其中的许多对象会被频繁重绘;

    大多数 Canvas 绘图 API 都没有定义在 <canvas>元素本身上,而是定义在通过画布的getContext()方法获得的一个"绘图环境"对象上。Canvas API也使用了路径的表示法。但是,路径由一系列的方法调用来定义,而不是描述为字母和数字的字符串,比如调用 beginPath() 和 arc() 方法。一旦定义了路径,其他的方法,如 fill(),都是对此路径操作。

    DEMO传送门:https://jsfiddle.net/gaogy/rzss4mmr/

    SVG

    SVG是英文Scalable Vector Graphics的缩写,意为可缩放矢量图形,用来定义用于网络的基于矢量的图形,其使用 XML 格式定义图像,并且具有如下特点:

    • 不依赖分辨率,基于矢量图;
    • 支持事件处理器;
    • 最适合带有大型渲染区域的应用程序(比如谷歌地图);
    • 复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快);
    • 不适合游戏应用;

    来看一个简单的示例,用SVG画了一个圆:

    <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> 
      <rect x="50" y="20" rx="20" ry="20" width="150" height="150" 
      style="fill:red;stroke:black;stroke-5;opacity:0.5"/> 
    </svg> 

    SVG 代码以 <svg> 元素开始,包括开启标签<svg> 和关闭标签</svg> 。这是根元素。width 和 height 属性可设置此 SVG 文档的宽度和高度。version 属性可定义所使用的 SVG 版本,xmlns 属性可定义 SVG 命名空间。

    SVG 的 <circle> 用来创建一个圆。cx 和 cy 属性定义圆中心的 x 和 y 坐标。如果忽略这两个属性,那么圆点会被设置为 (0, 0)。r属性定义圆的半径。

    下面主要是介绍SVG中的几个用于动画的元素,它们分别是:

    <animate>:通常放置到一个SVG图像元素里面,用来定义这个图像元素的某个属性的动画变化过程; 

    <animateMotion>:元素也是放置一个图像元素里面,它可以引用一个事先定义好的动画路径,让图像元素按路径定义的方式运动;

     <animateTransform>:元素对图形的运动和变换有更多的控制,它可以指定图形的变换、缩放、旋转和扭曲等;

     <mpath>:元素的用法在上面的例子里出现过,它是一个辅助元素,通过它,<animateMotion>等元素可以引用一个外部的定义的<path>。让图像元素按这个<path>轨迹运动;

    DEMO传送门:https://jsfiddle.net/gaogy/ac4avoqk/

    WebGL

    WebGL使得网页在支持HTML <canvas>标签的浏览器中,不需要安装任何插件,便可以使用基于 OpenGL ES 2.0 的 API 在 canvas 中进行3D渲染。 WebGL 程序由JavaScript的控制代码,和在计算机的图形处理单元(GPU)中执行的特效代码(shader code,渲染代码) 组成。

    WebGL.png WebGL 本质上是基于光栅化的 API,而不是基于 3D 的 API。WebGL 只关注两个方面,即投影矩阵的坐标和投影矩阵的颜色。使用 WebGL 程序的任务就是实现具有投影矩阵坐标和颜色的 WebGL 对象即可。可以使用"着色器"来完成上述任务。顶点着色器可以提供投影矩阵的坐标,片段着色器可以提供投影矩阵的颜色。

    由于WebGL的体系比较庞大,三言两语说不完,所以以下仅提供各种传送门了:

    • WebGL 参考资料:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL
    • WebGL API:https://developer.mozilla.org/zh-CN/docs/Web/API/WebGL_API

     

    几个常用的动画库

    • Ani.js -- 基于CSS动画的生命处理库
    • Dynamics.js -- 创建具有物理运动效果动画的js库
    • Animate.css -- 齐全的CSS3动画库
    • Three.js -- 让用户通过javascript入手进入搭建webgl项目的类库
  • 相关阅读:
    Atitit.ati orm的设计and架构总结 适用于java c# php版
    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
    Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
    Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
    atitit.基于  Commons CLI 的命令行原理与 开发
    atitit.基于  Commons CLI 的命令行原理与 开发
    atitit.js 与c# java交互html5化的原理与总结.doc
  • 原文地址:https://www.cnblogs.com/yaoyao-sun/p/10365022.html
Copyright © 2011-2022 走看看