讲真,会写动画的前端才是好开发!

动画是通过把某一动态过程分解后,画成许多动作瞬间的画幅,再用摄影机连续拍摄成一系列画面,给视觉造成连续变化的图画。它的基本原理与电影、电视一样,都是视觉暂留原理。医学证明人类具有“视觉暂留”的特性,人的眼睛看到一幅画或一个物体后,在0.34秒内不会消失。

利用这一原理,在一幅画还没有消失前播放下一幅画,就会给人造成一种流畅的视觉变化效果。相信很多人都看过动画片,或者手翻书,其实它们与电视、电影的原理都是一样的。

动画如何实现

1. Javascript直接实现动画;

2. css3动画中的transition 和 animation;

3. Canvas动画;

4. SVG(可伸缩矢量图形);

1. Javascript 直接实现动画

Javascript直接实现动画,主要是通过setInterval或setTimeout方法的回调函数来持续调用改变某个元素的CSS样式以达到元素样式变化的效果,或者使用requestAnimationFrame;

示例:

上面示例的效果是一个灰色的小方块,慢慢的从左边,移动到屏幕右边的动画,每隔16ms就把方块的左外边距增加1px。尽管过程看起来很连贯,但是这种方法依然存在一些问题。

因为JavaScript是单线程的,setTimeout是异步操作,加入任务队列后,当js引擎线程中同步代码执行完才会从任务队列中取出执行,可能发生阻塞。另外setTimeOut会导致页面频繁性重排重绘,消耗性能,一般应该在桌面端浏览器,而且不同浏览器对setTimeOut的解析也是不同的,导致同一动画在不同浏览器下效果不一致,在移动端上使用会有明显的卡顿。

requestAnimationFrame实现动画的优点是可以避免不必要的过度重绘,但是整体性能和可调节性都不如css3动画。

2. css3 实现动画

Transition

Transition可以实现过渡动画的效果,但是transition并不能实现独立的动画,只能在某个标签元素样式或状态改变时进行平滑的动画效果过渡,而不是马上改变。 transition抓住了所设置变化属性的起始态和完成态,通过设定的速度曲线来完成动画,不支持自定义中间的状态。可以设置发生变化的css属性,默认为all,则所有变化的属性都会在触发时,以动画的形式展现出来。如果把transition和transform配合使用,对元素进行平移、倾斜、缩放,使动画更加丰富生动。

transition语法如下:

transition:property duration timing-function delay;

具体属性值介绍如下:

示例:

Animation

Animation 算是真正意义上的CSS3动画。使用animation属性制作动画可以更加灵活的设置动画,通过对关键帧及其状态以及循环次数的控制,页面元素会在对应的时间按照设定好的样式改变进行平滑过渡。不过区别于Transition,Animation作用于元素本身而不是样式属性,不局限于只有初始状态和结束状态,可以实现更自由的动画效果。

animation语法如下:

animation: nameduration timing-function delay iteration-count direction;

具体属性值介绍如下:

关键帧定义:

示例:

感兴趣的小伙伴请看这里(如无法打开,请复制链接到浏览器):

http://www.cnblogs.com/yingzi1028/p/7768595.html

使用CSS3 transition和 animation实现动画,它最大的优势是摆脱了js的控制,并且能利用硬件加速以及实现复杂动画效果,但是会存在浏览器兼容性问题。

3. canvas 动画

canvas 作为H5新增元素,是页面图形绘制的容器,借助Web API来实现动画的。通过getContext()获取元素的绘制对象,通过clearRect不断清空画布并在新的位置上使用fillStyle绘制新矩形内容实现页面动画效果。

上面的例子画出了一幅1000*600,淡蓝色背景有动态下雪效果的图片,其中一帧如下图所示:

canvas的主要优势是可以应对页面中多个动画元素渲染较慢的情况,完全通过 javascript来渲染控制动画的执行,可用于实现较复杂动画。同样都是使用编码的方式由前端开发工程师完成动画效果,canvas要比原生js效率高的多,流畅的多能够轻松的实现更多的动画效果。

canvas的缺点是没有提供为其内部元素添加事件监听的方法,需要自己动手实现,使其内部元素能够响应事件。首先获得鼠标在 canvas 上的坐标,计算当前坐标在哪些元素内部,然后对元素进行相应的操作。配合自定义事件,我们就可以实现为 canvas 内的元素添加事件监听的效果。

4. SVG动画

SVG用来定义用于网络的基于矢量的图形,其使用 XML 格式定义图像,由SVG元素内部的元素属性控制。Svg不依赖分辨率,基于矢量图,支持事件处理,最适合带有大型渲染区域的应用程序。

上面的例子实现的是一个跳动的心的动图,其中一帧如下图所示:

想看动图的小伙伴请看这里(如无法打开,请复制链接到浏览器):

https://code.h5jun.com/kul

SVG的一大优势是含有较为丰富的动画功能,原生绘制各种图形、滤镜和动画,并且能被js调用。

但是,另一方面元素较多且复杂的动画使用svg渲染会比较慢,CSS3动画的出现让svg的应用变得相对少了。

另外,还有在不同框架下,也都有自己实现动画的方法,例如jQuery中的show、slide、fade以及animate方法,或者angularJs中的ngAnimate通过添加或移除 class,使用预定义的样式类来设置 HTML 元素的动画,或者animate()方法, 在组件对应的模板上直接加动效,AnimationBuilder, 在自定义指令中给宿主元素加动效。

看到这里大家一定很疑惑,既然实现动效的方法有那么多种,那么对于组件来说,应该如何做选择?

这就要结合组件来看了,首先使用 css3 中 animation 和 transition实现,这种实现方式除了IE9及其以下版本不兼容之外,其他浏览器之下都有很好的兼容性。这种实现方式能够将组件样式与组件动画分离开展示,非常有利于后期维护,对国际化和换肤也是十分友好的。

然后根据情况选择angular的ngAnimate或者jQuery中的.animate()方法,因为这两种方法的使用都是有前提和限制的,并不能实现左右的动画效果。

最后,如果以上方法还不能满足你的需求,那就只能使用 JavaScript 中的 setInterval 和setTimeOut 方法实现了,在定时器中不断修改某个样式的值,直到达到临界值,实现动画。

— END —

别忘了给作者:蔡萌点赞呦!

有什么想对作者说的吗?快来留言吧!

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180418A1APGM00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券