【青训营】- 如何实现前端动画

278 阅读4分钟

01 动画的基本原理

在开始之前,我们先来了解一下动画是什么,以及动画的基本原理。

顾名思义,动画是通过快速连续排列彼此差异极小的连续图像来制造运动的错觉和变化错觉的过程。

动画的基本原理就是利用人眼的视觉暂留特性,一般每秒10-12帧人会认为画面是流畅的,因此制作动画需要定义一个开始状态和一个结束状态,并在中间添加多个过渡帧,从而实现动画的效果。

02 前端动画分类

前端动画主要分为以下三个类别:

  1. css动画
  2. svg实现动画
  3. js实现动画

接下来我们就分别介绍一下这几种动画。

CSS动画

css的形体变换主要是用到TransformAPI,并且只能转换由盒模型定位的元素。通过css动画,可以实现简单的移动,旋转,缩放,倾斜等。

css也可以用keyframe实现动画,通过在动画序列中定义关键帧的样式来控制css动画序列中的中间步骤。

SVG动画

对于SVG动画,我们可以在这里看几个例子。

html代码

<svg viewBox="0 0 340 333">

  <path class="path" fill="white" stroke="black" stroke-width="4" d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
	s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
	C46.039,146.545,53.039,128.545,66.039,133.545z"/>
  
</svg>

css代码

.path {
  stroke-dasharray: 20;
  stroke-dashoffset: 0;
  /*animation: dash 5s linear alternate infinite;*/ 
}

/*@keyframes dash {
  from {
    stroke-dashoffset: 822;
  }
  to {
    stroke-dashoffset: 0;
  }
}*/

首先,我们可以看一下运行的效果。

image.png

可以看到,现在的图形是静态的,因为我们还没有为图形添加SVG动画。我们仅仅是做了一个静态的笔触。我们是使用stroke-dashoffset、stroke-dasharray来实现的笔画效果。stroke-dashoffset代表需要填充的路径,stroke-dashoffset是dash模式开始位置的偏移量。我们将需要描的边比作一个瓶子,stroke-dasharray就相当于往瓶子里倒钢笔水,只不过我倒进去以后,每隔一段距离都有一些气泡。相当于注入墨水的时候从哪个点开始注入。

我们可以将注释掉的代码去掉注释,看一下现在的效果。

GIF 2021-8-19 22-13-53.gif

现在可以看到,我们的图片已经动起来了。这是因为我们添加了关键帧动画。我们更改了stroke-dashoffset的数值,让它随着时间而变化,就会造成动态的效果。 现在可以看到,由于我们设置stroke-dasharray的值为20,因此这个笔触是不连贯的,如果我们想要让笔触连贯起来,可以使用下面这个函数:getTotalLength()来获取路径的总长度,这样就可以获得一个完整的笔触。

image.png

获取到的路径总长度为821,因此我们将stroke-dasharray改为821,就可以得到下图的效果。

GIF 2021-8-20 0-12-45.gif

JS动画

js可以实现复杂的动画,也可以操作canvas动画API上进行绘制。

JavaScript动画应该通过requestAnimtionFrame,而不是setTimeOut和setInterval,因为该内置方法允许设置回调函数以在浏览器准备重绘时运行。通常这很快,但确切的时间取决于浏览器。

03 如何做选择

CSS动画

优点: 简单、高效、声明式的 不依赖于主线程,采用硬件加速(GPU)简单的控制keyframe animation的播放和暂停。

缺点: 不能动态修改或定义动画内容 不同的动画无法实现同步 多个动画无法彼此堆叠。

适用场景: 简单的h5/宣传页。

SVG动画

css优点:

浏览器会对css3动画做一些优化,导致css3动画性能上稍有优势,(新建一个图层来跑动画)。 css动画的代码相对简单。

css缺点:

  1. 动画控制上不够灵活。
  2. 兼容性不佳。
  3. 部分动画无法实现(视差效果、滚动动画)。

js优点:

  1. 使用灵活,同样在定义一个动画的keyframe序列时,可以根据不同的条件调节若干参数(JS动画函数)改变动画方式。(CSS会有非常多的代码冗余)
  2. 对比与CSS的keyframe粒度更粗,css本身的时间函数是有限的。
  3. CSS很难做到两个以上的状态转化(要么使用关键帧,要么需要多个动画延时触发,再想到要对动画循环播放或暂停倒序等,复杂度极高)。

js缺点:

使用到JS运行时,调优方面不如CSS简单,CSS调优方式固定。-对于性能和兼容性较差的浏览器,CSS可以做到优雅降级,而JS需要额外代码兼容。

总结

  1. 当您为UI元素采用较小的独立状态时,使用CSS。
  2. 在需要对动画进行大量控制时,使用JavaScript。
  3. 在特定的场景下可以使用SVG,可以使用CSS或JS去操作SVG变化。