• 动画概念和实现介绍


     

    动画是指由许多帧静止的画面,以一定的速度(如每秒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项目的类库
  • 相关阅读:
    webstorm实现手机预览页面
    git 远端版本回退
    Vue开发中的移动端适配(px转换成vw)
    测试web-view,实现小程序和网页之间的切换
    mysql 字符集研究
    Openssl
    Android Activity 去掉标题栏及全屏显示
    Android中的 style 和 theme
    Android sharedPreferences 用法
    Vim 字符集问题
  • 原文地址:https://www.cnblogs.com/yaoyao-sun/p/10365022.html
Copyright © 2020-2023  润新知