前端动画实现
前端动画实现
1、动画的基本原理
什么是动画?
动画是通过快速连续排列批次差异极小的连续图像来制造运动错觉和变化错觉的过程 ——维基百科
关键词:
- 快速
- 连续排列
- 彼此差异极小
- 制造错觉
动画的历史与发展:
动画早在五千年前就存在了:
- 常见的前端动画技术:
Sprite 动画、CSS 动画、JS 动画、SVG 动画、WebGL 动画 - 按应用分类:
UI 动画、基于Web 的游戏动画和动画数据可视化
历史上第一个网站:
计算机动画原理:
帧:连续变换的多张画面,其中的每一幅画面都是一帧。
帧率:用于度量一定时间段内的帧数,通常的测量单位是FPS (frame persecond) 。
帧率与人眼:一般每秒10-12帧人会认为画面是连贯的,这个现象称为视觉暂留。对于一些电脑动画和游戏来说低于30FPS会感受到明显卡顿,目前主流的屏幕、显卡输出为60FPS,效果会明显更流畅。
空白的补全方式:
- 补间动画:
传统动画,主画师绘制关键帧,交给清稿部门,清稿部门的补间动画师补充关键帧进行交付。(类比到这里,补间动画师由浏览器来担任,如keyframe,transition) - 逐帧动画(Frame By Frame) :
从词语来说意味着全片每一帧逐帧都是纯手绘。(如css 的steps实现精灵动画)
2、前端动画分类
CSS动画
animation
- animation-name : 指定应用的一系列动画,每个名称代表一个由@keyframes定义的动画序列
- animation-duration : 制定一个动画周期的时长(默认为0秒,表示无动画)
- animation-timing-function : 定义CSS动画在每一动画周期中执行的节奏
- animation-delay : 定义动画于何时开始
- animation-iteration-count : 定义动画在结束前运行的次数,可以是1次也可以是无限循环
- animation-direction : 定义动画是否反向播放
- animation-fill-mode : 设置CSS动画在执行之前和之后如何将样式应用于目标
- animation-play-state : 定义一个动画是否运行或暂停
transform
- translate : 平移
- scale : 缩放
- rotate : 旋转
- skew : 倾斜
transition API
- transition-property : 指定哪个或者哪些CSS属性用于过渡
- transition-duration : 指定过度的时长
- transition-timing-function : 指定一个函数,定义属性值怎么变化
- transition-delay : 指定延迟
@Keyframe
- from to
- 百分比
CSS动画总结:
优点 : 简单、高效 声明式的 不依赖于主线程,采用硬件加速(GPU) 简单的控制keyframe animation 的播放盒暂停
缺点 : 不能动态修改或定义动画内容 不同的动画无法实现同步 多个动画无法堆叠
适用场景 : 简单的h5活动/宣传页
推荐库 : animation.css、shake.css
svg动画
SVG动画的实现方式 SVG时基于XML的矢量图形描述语言,实现方式一般有以下三种:
- SMIL(同步多媒体集成语言),原始的兼容性不好,不过多讨论
- JS: 一般是以下两个属性配合使用实现笔画效果。 stroke-dashoffset: |
需要填充的路径 stroke-dasharray: | dash模式开始位置的偏移量 - CSS: 主要使用animation、transform、transition来实现动画,类似于css动画。
svg动画总结:
优点:通过矢量元素实现动画,不同的屏幕下均可获得较好的清晰度。可以实现一些特殊的效果:描字,形变,墨水扩散等。
缺点:使用方式较为复杂,计算量比较大,过多使用可能会带来性能问题。
JS动画
可以通过JS控制CSS的属性值,以实现动画,或者操作canvas上的API进行动画绘制。
JS动画总结:
优点:使用灵活,调节参数方便;可以进行多个状态的组合执行或联动。
缺点:调优不如CSS简单;对于性能和兼容性差的浏览器,JS需要写很多适配代码。
总结
- 为UI 元素采用较小的独立状态时,使用CSS。
- 在需要对动画进行大量控制时,使用JavaScript。
- 在特定的场景下可以使用SVG,可以使用CSS或JS去操作SVG变化。
3、实现前端动画
JS动画函数封装:
JavaScript动画应该通过requestAnimationFrame.该内置方法允许设置回调函数以在浏览器准备重绘时运行。通常这很快,但确切的时间取决于浏览器。当页面在后台时,根本没有重绘,所以回调不会运行:动画将被暂停并且不会消耗资源。
// *@param draw {function} 绘制函数
// @param easing {function} 缓动函数
// @param duration {number} 持续时间
function animate ({easing, draw, duration}) {
let start = performance.now();
return new Promise(resolve => {
requestAnimationFrame(function animate(time) {
let timeFraction = (time - start) / duation;
if (timeFraction > 1) timeFraction = 1;
let progress = easing(timeFraction);
draw(progress);
if(timeFraction < 1) {
requestAnimationFrame(animate);
} else {
resolve();
}
})
})
}
- draw绘制函数:
可以把draw想象成一只画笔,随着函数的执行,这个画笔的函数会反复被调用,并传入当前执行的进度progress,progress是一个介于0-1的number数字。 - easing缓动函数
缓动函数决定了时间在线性增长过程中,实际的执行进度的变化,这个变化可以是线性的,也可以是非线性的,或者多维度的。 - duration持续时间
动画的持续时间,单位是毫秒(返回Promise的原因:动画可以是连续的,支持通过then函数或await进行顺序调用)
4、工作实践
动画代码示例:
设计网站:
动画资源:
SVG :
- Snap.svg-现代SVG图形的JavaScript库。
- Svg.js -用于操作和动画SVG的轻量级库。
js :
- GSAP – JavaScript动画库。
- TweenJs – 一个简单但功能强大的JavaScript补间/动画库。Create]S库套件的一部分。
- Velocity-加速的JavaScript动画。
css :
- Animate.css – CSS动画的跨浏览器库。像一件简单的事情一样容易使用。
canvas :
- EaselJs – EaselS是一个用于在 HTML5中构建高性能交互式2D内容的库
- Fabric.js -支持动画的JavaScript 画布库。
- Paper.js -矢量图形脚本的瑞士军刀- Scriptographer使用HTML5Canvas移植到JavaScript和浏览器。
- Pixijs -使用最快、最灵活的2D WebGL渲染器创建精美的数字内容。
原文链接:https://juejin.cn/post/7350836720256647209 作者:会思想的苇草i