引言
前端开发过程中,动画是必不可少的,但是实现动画有哪些方式呢?这里我总结以下几种前端实现动画的方式。
1. JS 实现动画
JS 实现动画的方式有很多,通过 setTimeout、setInterval 和 requestAnimationFrame 都可以实现动画。
let elem = document.getElementById('elem');
setInterval(function () {
elem.style.left = parseInt(elem.style.left) + 10 + 'px';
}, 20);
2. CSS3 实现动画
CSS3 实现动画的方式也有很多,通过 transition、animation 和 keyframes 可以实现动画。同样的我们可以用序列帧、精灵图实现较为复杂的动画。
#elem {
transition: left 2s;
}
#elem:hover {
left: 500px;
}
@keyframes move {
0% {
left: 0;
}
100% {
left: 500px;
}
}
#elem {
animation: move 2s;
}
3. SVG 实现动画
SVG 是一种基于 XML 的图像格式,非常类似于 HTML 的工作方式。它为许多熟悉的几何形状定义了不同的元素,这些元素可以在标记中组合以产生二维图形。
同样高清的质地,矢量图不畏惧放大,体积小。
<svg width="120" height="120">
<circle cx="60" cy="60" r="50" fill="#ff0000">
<animate
attributeName="fill"
begin="mouseenter"
dur="2s"
from="#ff0000"
to="#00ff00"
/>
</circle>
</svg>
4. Canvas 实现动画
Canvas 是 HTML5 提供的一个基于 JavaScript 的 2D 绘图 API,它可以在网页上绘制动态的图像。可以完全通过 JavaScript 绘制出各种图形,比如线条、圆形、文字等。
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
5. WebGL 实现动画
WebGL(Web 图形库)是一个 JavaScript API,可在任何兼容的 Web 浏览器中渲染高性能的交互式 3D 和 2D 图形,而无需使用插件。
WebGL 相对来说比较复杂,通过 vertexShader 和 fragmentShader 可以实现动画。
var gl = canvas.getContext('webgl');
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);
6. GIF 实现动画
GIF 是一种无损压缩的位图文件格式,可以存储单色图像、全彩色图像和索引颜色图像。它支持动画效果,但是 GIF 的体积较大,不适合用于网络传输。
7. WebP 实现动画
WebP 是一种支持有损压缩和无损压缩的图片文件格式,由 Google 开发。它类似于 JPEG、PNG 等图片格式,但具有更优异的图像数据压缩算法,能带来更加流畅、丰富的图像展示效果。
8. APNG 实现动画
APNG(Animated Portable Network Graphics)是一种支持动画的图片格式,可以存储单色图像、全彩色图像和索引颜色图像。它支持透明度、动画效果和 Alpha 通道,并且体积较小。
压缩率上来说,APNG 优于 WebP;从兼容性上来说 WebP 的兼容性明显高于 APNG。
使用时需要注意
兼容性
问题,低端机可能不支持。
9. Lottie 实现动画
Lottie 是一个开源的动画库,可以将 JSON 格式的动画文件转换为 Web、Android 和 iOS 原生应用中的动画。
import lottie from 'lottie-web';
const anim = lottie.loadAnimation({
container: document.getElementById('anim'),
renderer: 'svg',
loop: true,
autoplay: true,
animationData: require('./data.json'),
});
10. PAG 实现动画
PAG 是腾讯自主研发的一个开源项目,它同时支持「矢量预合成」导出和「BMP 预合成」导出两种方式。PAG 对文件的解码速度更快压缩率更高,还能够动态修改替换文本和图片等资源。
PAG 官网:https://pag.io/
11. SVGA 实现动画
SVGA 是由 YY 团队开发出来的一种跨平台的开源动画格式,同时兼容 iOS / Android / Web。SVGA 除了使用简单,性能卓越,由于动画文件体积更小,播放资源占用更优,动画还原效果更好;同时让动画开发分工明确,各自专注各自的领域,大大减少动画交互的沟通成本,提升开发效率,动画设计师专注动画设计,通过工具输出 svga 动画文件,提供给开发工程师在集成 svga player 之后直接使用。
SVGA 不同于 Lottie,Lottie 需要在 Player 一层完整地将 After Effects 所有逻辑实现,而 SVGA 则将这些逻辑免去。也因此,SVGA 可以同时支持 Flash。SVGA 做的事情,实际上,非常简单,Converter 会负责从 Flash 或 AE 源文件中提取所有动画元素(位图、矢量),并将其在时间轴中的每帧表现(位移、缩放、旋转、透明度)导出。Player 会负责将这些信息还原至画布上。
SVGA 官网:https://svga.dev/
12. MP4 实现动画
MP4 动效,因其压缩率高、硬解性能好、可支持复杂动效效果(3D、粒子、描边等)
MP4 动画的实现原理简单来讲就是使用 canvas 的 drawImage 方法将 video 容器解析后的视频画面逐帧绘制到 canvas 画布上。
- 相比 Webp, Apng 动图方案,具有高压缩率(素材更小)、硬件解码(解码更快)的优点
- 相比 Lottie,能实现更复杂的动画效果(比如粒子特效)
总结
前端实现动画的方式很多,不同的方式有不同的优缺点。
JS、CSS3 实现简单的动画,兼容性较好。
SVG、Canvas、WebGL 实现较为复杂的动画,但是比较复杂。
GIF、WebP、APNG 实现动画,前端只需要导入即可,使用很简单。
图片质量上:与 GIF 相比,APNG/Webp 格式的图片,不仅支持支持透明像素。并且,APNG/WebP 文件格式的图片不会有锯齿,颗粒感等问题。 体积大小上:GIF 采用 LZW 压缩算法,而 APNG 采用的是 Deflate 压缩算法,WebP 使用的是基于 VP8 视频格式的帧内编码,并以 RIFF 作为容器格式。在相同的情况下 APNG/Webp 文件体积会更小,并且效果更佳。 颜色上:GIF 最多支持 256 种颜色,而 APNG/Webp 支持真彩色,颜色更丰富。 兼容性上:GIF 兼容性较好,WebP/APNG 较差。
Lottie、PAG、SVGA 都是开源的动画库,可以用于 Web、Android 和 iOS 原生应用中。个人经验来看 Web 端使用 Lottie 较多,PAG 坑比较多。