前端动效讲解与实战

2022-09-26 00:00:00 图片 渲染 属性 动画 骨骼

本文将从各个角度来对动画整个体系进行分类,并且介绍各种前端动画的实现方法,后我们将总结在实际开发中的各个场景的动画选择方案。

一、背景

前端动画场景需求多

对众多动画场景的技术实现方案选择上比较模糊

各动画方案的优劣及适用场景认识模糊

现有动画库太多,不知道选哪个

主流动画库的适用场景认识模糊

下面首先让我们从各个角度来对动画整个体系进行分类,让我们清晰的了解动画整个体系。

二、分类

2.1  用途角度

首先我们从动画的用途或者说是业务的角度来进行区分,将我们平时的动画分为展示型动画和交互型动画。

2.1.1 展示型动画

类似于一张GIF图,或者一段视频。比如在开启宝箱的时候,我们会加入一个切场过渡动画,来替代原有的生硬等待结果。

展示型动画在实际使用的场景中,实现的方法很多,比如用GIF图,canvas,CSS3动画等,但是终输出的结果是不带有交互的,也就是从动画起始状态到结束状态一气呵成,这个过程用户可以感知,但是无法参与

2.1.2 交互型动画

用户自已参与的,对于交互性动画而言,我们可以在动画播放的某个时间节点触发相应的操作,进而让用户参与到其中,常见的例子红包雨,不仅仅能提升用户的体验,还能提升我们的产品的多元性。

然而交互性动画经常面临的一个问题就是,通过原生代码实现交互动画是很复杂的,同时性能和兼容性是不得不认真考虑的问题,比较好的解决方案还是寻求相关的框架。

2.2 绘制技术角度

不管采用什么方式来制作动画,终呈现到前端页面的无非是以下三种形式:

  1. Canvas
  2. div
  3. SVG

 

PS:为了简单也可以用视频,但除非动画的播放场景固定,不然移动端视频在不同app、不同机型、不同系统的播放显示都不太一样,容易踩不少坑。

2.2.1 不同绘制技术的性能差异

Canvas

  • 效率高、性能好、可控性高,只能处理位图,内存占用恒定
  • 依赖分辨率
  • 不支持事件处理器
  • 弱的文本渲染能力
  • 能够以 .png 或 .jpg 格式保存结果图像
  • 适合图像密集型的游戏,其中的许多对象会被频繁重绘

div

  • 包括CSS控制的DOM动画、JS控制的DOM动画
  • 比较适合简单的数量较少的复杂度较低的动画

SVG

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

2.2.2  Canvas和SVG比较

一句话总结:都是2D做图,svg是矢量图,canvas是位图。canvas 是逐像素进行渲染的,适合游戏。

SVG

  • SVG绘制的是矢量图,缩放不影响显示,所以适合带有大型渲染区域的应用程序(比如谷歌地图)
  • SVG 是一种使用 XML 描述 2D 图形的语言。
  • SVG 基于 XML,这意味着 SVG DOM 中的每个元素都是可用的。您可以为某个元素附加 JavaScript 事件处理器。
  • 在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象的属性发生变化,那么浏览器能够自动重现图形。

Canvas

  • Canvas 通过 JavaScript 来绘制 2D 图形。
  • Canvas 是逐像素进行渲染的。
  • 在 Canvas 中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。
  • Canvas只占用一个DOM节点,在做一些烟*花、飘雪等运动元素很多的动画时,会比CSS/SVG性能好。

 

性能比较

  • 一般情况下,随着屏幕大小的增大,canvas将开始降级,因为需要绘制更多的像素。
  • 随着屏幕上的对象数目增多,SVG 将开始降级,因为我们正不断将这些对象添加到 DOM 中。
  • 这些度量不一定准确,以下方面的不同一定会引起变化:实现和平台、是否使用完全硬件加速的图形,以及 JavaScript 引擎的速度。

 

2.3 动画类型角度

前端动效开发,首先应该确定的是

动画用途->确认动画类型->确认绘制技术->确认动画的实现方式。

虽然终呈现动画的载体(绘制技术)就三种,但实现动画的方式却很多,得从动画类型出发讨论动画的实现方式:

(1)逐帧动画(序列帧动画)

  • GIF实现
  • CSS实现(animation)
  • JS+DOM实现
  • JS+canvas实现

(2)补间动画(Tween动画\关键帧动画)

  • CSS实现(transition、animation等)使用一些缓动函数
  • JS实现

(3)SVG动画

  • 使用 XML 格式定义图形
  • 可以用AI等SVG编辑工具生成SVG图片后,配合anime.js、GSAP等现有库进行动画制作

(4)骨骼动画

  • 一般采用Spine、DragonBones等工具导出相应资源图片和JSON动画配置资源后使用。

(5)3D动画

  • DOM操作用CSS 3D实现。(perspective属性、css3d-engine)
  • 场景搭建用webGL(Three.js等)
  • 3D模型动画用Blender或maya等制作完成后导出使用

2.3.1 逐帧动画(序列帧动画)

逐帧动画是在时间帧上逐帧绘制帧内容,由于是一帧一帧的画,所以逐帧动画具有非常大的灵活性,几乎可以表现任何想表现的内容。

由于逐帧动画的帧序列内容不一样,不仅增加制作负担而且终输出的文件量也很大,但它的优势也很明显:因为它相似与电影播放模式,很适合于表演很细腻的动画,如3D效果、人物或动物急剧转身等等效果。

所以逐帧动画的实现核心是什么,就是将我们的这些静态的图片进行快速的循环播放,形成了一个动态的动画效果。这就是帧动画。

2.3.1.1 GIF实现

我们可以将帧动画导出成GIF图,GIF图会连续播放,无法暂停,它往往用来实现小细节动画,成本较低、使用方便。但其缺点也是很明显的:

  1. 画质上,GIF 支持颜色少(大256色)、Alpha 透明度支持差,图像锯齿毛边比较严重;
  2. 交互上,不能直接控制播放、暂停、播放次数,灵活性差;
  3. 性能上,GIF 会引起页面周期性的绘画,性能较差。

 

2.3.1.2 CSS实现

CSS3帧动画是我们今天需要重点介绍的方案,核心的是利用CSS3中Animation动画,确切的说是使用animation-timing-function 的阶梯函数 steps(number_of_steps, direction) 来实现逐帧动画的连续播放。

帧动画的实现原理是不断切换视觉内图片内容,利用视觉滞留生理现象来实现连续播放的动画效果,下面我们来介绍制作CSS3帧动画的几种方案。

(1)连续切换动画图片地址src(不推荐)

我们将图片放到元素的背景中(background-image),通过更改 background-image 的值实现帧的切换。但是这种方式会有以下几个缺点,所以该方案不推荐。

  • 多张图片会带来多个 HTTP 请求
  • 每张图片加载会造成图片切换时的闪烁
  • 不利于文件的管理

(2)连续切换雪碧图位置(推荐)我们将所有的帧动画图片合并成一张雪碧图,通过改变 background-position 的值来实现动画帧切换。分两步进行:

步骤一:

 将动画帧合并为雪碧图,雪碧图的要求可以看上面素材准备,比如下面这张帧动画雪碧图,共20帧。

相关文章