前端实现动画的几种方式

作者: shaokang 时间: September 14, 2024字数:3325

引言

前端开发过程中,动画是必不可少的,但是实现动画有哪些方式呢?这里我总结以下几种前端实现动画的方式。

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 坑比较多。