前端动画调研-V1

展示型动画在实际使用的场景中,实现的方法很多,比如用 gif图canvascss3 动画等,但是最终输出的结果是不带有交互的,也就是从动画起始状态到结束状态一气呵成,这个过程用户可以感知,但是无法参与。对于交互性动画而言,我们可以在动画播放的某个时间节点触发相应的操作,进而让用户参与到其中,最常见的例子比如红包雨,或者是我们世界杯踢足球的动画,不仅仅能提升用户的体验,还能提升我们的产品的多元性。然而交互性动画经常面临的一个问题就是,通过原生代码实现交互动画是很复杂的,同时性能和兼容性是不得不认真考虑的问题,比较好的解决方案还是寻求相关的框架。

二. 动画使用到的技术

  • CSS3 Animation
  • canvas
  • SVG
  • WebGL
  • 利用JavaScript驱动的动画

伴随着CSS3的发展,利用CSS3的 transform 和动画的 @keyframes 就可以完成很多酷炫的动画,但是CSS3的动画应用场景仅仅是展示型动画,只要动画开始,我们就无法控制动画的状态,而且对于复杂的动画,CSS3就显得很无力了。对于JavaScript驱动的动画,在一定程度上就可以弥补这些缺点,比如 anime.js 增加的 timeline 的概念,通过将各部分动画链式执行,从而完成更为复杂的动画,同时动画执行的各个阶段提供的回调函数也能让我们更方便的控制动画执行的状态,为交互提供了可能。对于 canvas ,在 canvas 上绘制的图形自身不支持 DOM 事件 ,只有 canvas 标签自身支持 DOM 事件监听。因此需要对 canvas 容器 的事件进行处理,实现相对应事件的监听及处理。 WebGL 可以为 canvas 提供硬件 GPU 加速渲染,借助使用系统GPU可以在移动端中更流畅的展示动画.

三. 相关技术的兼容性

  • 对于 CSS3的animation ,兼容性如下:
  • canvas 兼容性如下:
  • WebGL 兼容性如下:

可以看到,CSS3的animation和canvas支持性比较好,只有WebGL在Android 4.4 Browser 完全不支持,后续我们会提到PixiJs库,可以采用WebGL渲染,也可以优雅降级采用canvas渲染

四. 现有的几种方案

1. AE + bodymovin + Lottie

适用场景:主要还是展示型动画

简介:通过 AE 上的 Bodymovin 插件 将 AE 中制作好的动画导出成一个 json 文件,通过 LottieJSON 进行解析,最后以 SVG/canvas/html 的方式渲染动画。

官方文档:airbnb.io/lottie/ codepen仓库: codepen.io/collection/…

优点:

  • 跨平台,一次绘制、一次转换、随处可用
  • 文件更小,获取AE导出的 JSON ,最后通过 lottie 渲染为 canvas/svg/html格式
  • 可以通过api操纵动画的一些属性,比如动画速度;添加动画各个状态的回调函数
  • 动画都是在 After Effects 中创建的,使用 Bodymovin 导出,并且本机渲染无需额外的工程工作。
  • 解放前端工程师的生产力,提高设计师做动效的自由度

缺点:

  • Bodymovin 插件待完善,仍然有部分 AE 效果无法成功导出
  • 对于交互方面支持的还不是很好,更多的是用来展示动画
  • Lottiejson 文件的支持待完善,目前有部分能成功导出成 json 文件的效果在移动端上无法很好的展现
  • 很多AE的效果是不支持的 查看支持的特性:Supported Features

2. Anime.js

适用场景: 强展示+弱交互性动画

简介:Anime.js是一个轻量级的js驱动的动画库,主要的功能有 - 支持keyframes,连接多个动画 - 支持Timeline,为实现更为复杂的动画提供了可能 - 支持动画状态的控制playback control,播放,暂停,重新启动,搜索动画或时间线。 - 支持动画状态的callback,在动画开始,执行中,结束时提供回调函数 - 支持svg动画 - 可以自定义贝塞尔曲线 - 任何包含数值的DOM属性都可以设置动画

GitHub: github.com/juliangarni… codepen仓库: codepen.io/collection/… 文档演示: animejs.com/documentati…

功能介绍:

  • 一定程度上, anime.js 也是一个 CSS3动画库 ,适用所有的 CSS属性 ,并且实现的 @keyframes 能更方便的实现帧动画,替代CSS3复杂的定义方式。 使用对象数组的形式定义每一帧 戳我:keyframes实例

    anime({
        targets: 'div',
        translateX: [
            { value: 250, duration: 1000, delay: 500, elasticity: 0 }, //第一帧
            { value: 0, duration: 1000, delay: 500, elasticity: 0 }    //第二帧
        ]
    })  //这个例子实现了目标元素在两帧中实现水平位移
    复制代码
  • 提供的 Timeline 能实现更为复杂的动画效果,通过这个 Timeline ,我们可以维护不同的动画之间的关系,进而通过多个不同的动画组成一个更为复杂的动画。戳我:Timeline实例

    var myTimeline = anime.timeline();
    //通过.add()方法添加动画
    myTimeline
    .add({
        targets: '.square',
        translateX: 250
    })
    .add({
        targets: '.circle',
        translateX: 250
    })
    .add({
        targets: '.triangle',
        translateX: 250
    });
    复制代码
  • 动画播放的控制,常见的有暂停,重播,继续,动画状态的跟踪,自动播放,循环次数,抖动效果 戳我:playback controls实例

  • 为动画提供了回调函数,在动画或时间线完成的开始,期间或之时执行回调函数。戳我:callback实例

    var myAnimation = anime({
        targets: '#begin .el',
        translateX: 250,
        delay: 1000,
    
        begin: function(anim) {   //        callback
            console.log(anim.began); //     true after 1000ms
        }
    });
    复制代码
  • 支持 promise ,动画结束后,调用 anime.finishe d会返回一个 promise对象戳我:promise实例

  • 支持 svg 绘制路径,目前不支持 canvas绘制 戳我:SVG实例

  • 对于 input 这样带有数值的元素标签,也可以通过 anime实例 来设置动画 戳我:DOM ATTRIBUTES实例

    anime({
        targets: input,
        value: 1000, // Animate the input value to 1000
        round: 1 // Remove decimals by rounding the value
    });
    复制代码

优点:

  • 显而易见, anime.js 不仅实现了 CSS3动画 的深度封装,更多的是通过js驱动来实现操作动画的状态, timeline 实现了对于多个分支动画的管理,对于实现更为复杂的动画提供了可能
  • 通过 anime.js 提供的 playback controlscallback ,同时对于 promise 的支持,让我们对于动画的简单交互有了操作的空间
  • 虽然不支持 canvas ,但是支持 svg绘制路径 ,我对svg还不是很了解,待之后深入学习后,在做一个补充。
  • 浏览器兼容性比较好, Android 4 以上全部支持

缺点与不足:

  • anime.js 做展示型动画是可以胜任的,在做交互性动画方面还是需要看场景,它更多适合做一些小型的交互动画,类似于通过触摸屏幕踢足球这种强交互的, anime.js 就不是很有优势了。

3. PixiJs

适用场景:交互性动画,动画小游戏

简介:PixiJS是一个2D 渲染引擎, Pixi 主要负责渲染画面。可以创建丰富的交互式图形,动画和游戏,而无需深入了解WebGL API或处理浏览器和设备兼容性的问题。与此同时,PixiJS具有完整的WebGL支持,如果需要,可以无缝地回退到HTML5的canvas。PixiJs默认使用WebGL渲染,也可以通过声明指定canvas渲染,WebGL在移动端Android 4.4 browser并不支持,不过可以使用canvas优雅降级。

Github: github.com/pixijs/pixi… 官方文档: pixijs.download/release/doc… 官方网站:www.pixijs.com/ Examples: pixijs.io/examples/#/…

特性(摘自官方DOCS):

  • 支持 WebGL渲染
  • 支持 canvas 渲染 (官方称PixiJS在canvas渲染方面现在是最快的)
  • 非常简单易用的 API
  • 丰富的交互事件,比如完整的鼠标和移动端的触控事件
  • Pixi 使用和 Canvas Drawing 几乎一致的 api,但不同于 Canvas 的绘画 api,使用 Pixi 绘制的图形是通过 WebGLGPU 上渲染
  • 还有一系列特性需要在学习PixiJs之后了解

优势:

  • 最大优势莫过于通过 WebGL 来调用GPU渲染动画,这样极大的提升了性能
  • 无需深入了解 WebGL API 或者是 浏览器兼容性 (因为下面这条原因)
  • 支持 canvas 回退,当前设备不支持 WebGL 时, PixiJs 会使用 canvas渲染 动画
  • 完整的 DOCS ,比较活跃的社区,有利于深入的学习。不过我感觉PixiJs学习成本相对来说还是很高的

缺点:

Android 4.4

性能:

  • 对于手机版本 Android4.4 以上的手机,除了代码层面造成的性能不足,通过WebGL调用GPU渲染,性能还是有保障的。然而对于Android4.4只能使用canvas渲染,性能还是要看动画的复杂度,以及代码的优化

五. 总结

针对不同的动画需求,我总结了三种不同场景下的动画库。对于展示性的动画,我们完全可以使用第一种方案,让设计同学提供动画,我们利用动画导出的 JSON ,将动画还原为 svg/canvas/html 。如果场景是交互型或者需要做一个小游戏,可以采用第三种方案 PixiJs ,通过 WebGL 来渲染,利用硬件资源,极大的提升性能,在兼容性方面,对于不支持 WebGL 的浏览器,可以使用 canvas渲染平稳回退 。最后一种场景就是弱交互强展示,这种场景往往就是用户点击一下暂停执行相应操作,待操作完成继续播放动画, 交互方面比较偏弱 ,这种场景下可以采用第二种方案 Anime.js ,Anime.js不仅仅支持所有的css 属性,而且可以通过Timeline,callback, playback controls来控制动画执行的各个状态。而且兼容性满足我们的需求,在性能方面,只要不过多的造成 页面回流 ,多使用transform操作复合层,性能还是可以的(待多多尝试,就我看的几个例子性能还是不错的)。最后,从需求角度分析之后,从学习成本做个简单的小排名: PixiJs > Anime.js > lottie

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章