写在前面
作为一只前端仔,我们的使命就是在满足产品需求、实现交互设计的基础上,将最好的体验呈现给用户。在保证性能的同时,我们通常会给页面加一些动态效果,以增强页面的表现力并提升页面的交互体验。笔者将通过这篇文章将带你深入理解前端动画~
动画的基本原理
什么是动画?
动画是通过快速连续排列彼此差异极小的连续图像来制造运动错觉和变化错觉的过程。
动画的历史
其实动画在五千年前就存在了,看看这幅在伊朗沙赫尔-伊苏赫塔发现的画作。这是艺术家试图通过动画来表现图形运动的最早例子之一。这是五张山羊走向一棵树、爬上它、吃掉树叶然后又下来的照片。
通过现代动画技术可以将五张图拼接起来循环播放,就形成了动画。
计算机动画原理
计算图形学:
-
计算机视觉的基础,涵盖点、线、面、体、场的数学构造方法。
-
几何和图形数据的输入、存储和压缩。
-
描述纹理、曲线、光影等算法。
-
物体图形的数据输出(图形接口、动画技术),硬件和图形的交互技术。
-
图形开发软件的相关技术标准。
计算机动画: 计算机图形学的分支,主要包含2D、3D动画。
无论动画多么简单,始终需要定义两个基本状态,即开始状态和结束状态。没有它们,我们将无法定义插值状态,从而填补两者之间的空白。
帧:连续变化的多张画面,其中的每一幅画面都是一帧。
帧率:用于度量一定实践段内的帧数,通常的测量单位是FPS。
帧率与人眼:一般每秒10~12帧人会认为画面是连贯的,这个现象称为
视觉暂留
。
补间动画(关键帧动画):
传统动画,主画师绘制关键帧,交给清稿部门,清稿部门的补间动画师补充关键帧进行交付。(类比到这里,补间动画由浏览器来担任,如keyframe,transiton)
逐帧动画:
从词语来说意味着全片每一帧逐帧都是纯手绘(如steps实现雪碧图)
前端动画分类
CSS动画
CSS的形体变化 —— Transform API
只能转换由盒模型定位的元素。
Translate(移动)
transform: translate(100px)
transform: translate(50%)
transform: translate(100px,200px)
复制代码
Scale(缩放)
transform: scale(0.5)
transform: scale(0.5,2)
复制代码
Rotate(旋转)
transform: rotate(30deg)
复制代码
Skew(倾斜)
transform: skew(30deg,10deg)
复制代码
参数表示倾斜角度,单位deg
一个参数时:表示水平方向的倾斜角度;
两个参数时:第一个参数表示水平方向的倾斜角度,第二个参数表示垂直方向的倾斜角度。
Transition API(过渡动画)
DOM加载完成时或class发生变化时触发
-
transition-property 指定哪个或哪些CSS属性用于过渡。
-
transition-duration 指定过渡的时长
-
transition-function 指定一个函数,定义属性怎么变化。
-
transition-delay 指定延迟,即属性开始变化时与过渡开始发生时之间的时长
keframe实现动画:
关键帧@keyframes at-rule规则通过在动画序列中定义关键帧的样式来控制CSS动画序列中的中间步骤和转换。
@keyframes sliden{
from {
transform: translateX(0%)
transform: translateX(100%)
复制代码
CSS实现逐帧动画
通过
step API
来实现
总结一下CSS动画的优缺点:
优点:简单、高效、声明是的不依赖主线程主要采用硬件加速(GPU)简单的控制keyframe animation播放和暂停。
缺点:不能动态修改或定义动画内容 不同的动画无法实现同步,多个动画彼此堆叠。
应用场景:简单的H5活动/宣传页。
推荐库:animation.css、shake.css等。
svg动画
svg是基于XML的矢量图形描述语言,它可以与CSS和JS较好的配合,实现svg动画通常有三种方式:SMIL、JS、CSS
SMIL:同步多媒体集成语言
但是兼容性不理想,
不支持IE11浏览器
,这里不过多讨论。
使用JS来操作SVG动画自不必多说,网上已经有很多现成的类库。例如Snap.svg以及anime.js,都能让我们快速制作SVG动画。
JS笔画的原理
stroke-dashoffset、stroke-dasharray配合使用实现笔画效果。
stroke-dasharray:<length>|<percentage>(需要填充的路径)
stroke-dasharray:<length>|>percentage>(dash模式开始位置的偏移量)
优点:通过矢量元素实现动画,不同的屏幕下均可获得较好的清晰度。可以实现一些特殊的效果:描字,形变,墨水扩散等。
缺点:使用方式较为复杂,过多使用可能会带来性能问题。
JS动画
JS可以实现复杂的动画,也可以操作canvas动画API上进行控制。
如何做选择
CSS优点:
-
浏览器会对CSS3动画做一些优化,导致CSS3动画性能上稍有优势(新建一个图层来跑动画)。
-
CSS3动画的代码相对简单。 CSS缺点:
-
动画控制上不够灵活。
-
兼容性不佳
-
部分动画无法实现(视差效果、滚动动画)
JS优点:
-
灵活
-
对比与CSS的
keyframe
粒度更粗,CSS本身的时间函数是有限的,这块JS都可做弥补。
-
CSS很难做到两个以上的状态转化
JS缺点:
-
使用到JS运行时,调试方面不如CSS简单,CSS调试方式固定。
-
对于性能和兼容性较差的浏览器,CSS可以做到优雅降级,而JS需要额外代码兼容。
当您为UI元素采用较小的独立状态时,使用CSS。
当需要对动画进行大量控制时,使用JavaScript。
在特定的场景下可以使用SVG,可以使用CSS或JS去操作SVG变化。
动画实现
js动画函数封装
JavaScript动画应该通过
requestAnimationFrame
实现。该内置方法允许设置回调函数以在浏览器准备重绘时运行。通常这很快,但确切的实践取决于浏览器。
当页面在后台时,根本没有重绘,所以回调不会运行:动画将被暂停并且不会消耗资源。
function animate({ timing, draw, duration }) {
let start = performance.now();
requestAnimationFrame(function animate(time) {
// timeFraction为时间段,值为0-1之间
let timeFraction = (time - start) / duration;
if (timeFraction > 1) timeFraction = 1;
// 计算当前的动画状态
let progress = timing(timeFraction)
draw(progress);// 绘制
if (timeFraction < 1) {
requestAnimationFrame(animate);
复制代码
tips:
-
performance.now()和其他时间函数(Date.now())的区别,performance.now()会以恒定速度自增,精确到微妙级别,不易被篡改。
-
timing:计算动画进度的功能。获取从0到1的时间分数,返回动画进度,通常是从0到1。
-
duration:以毫秒为单位的总动画时间。
-
draw:绘制动画的函数。
工作实践
动画资源
动画代码示例:
CodePen
CodeSandbox
设计网站:
Dribble
动画制作工具(一般都是UE、UI同学使用):
2D: Animate CC、After Effects
3D: Cinema 4D、Blender、Autodesk Maya
SVG:
-
Snap.js——现代SVG图形的JavaScript库。
-
Svg.js——用于操作和动画SVG的轻量级库。
JS:
-
GSAP——JavaScript动画库。
-
TweenJS——一个简单但功能强大的JavaScript补间/动画库。CreateJS库套件的一部分。
-
Velocity——加速的JavaScript动画。
CSS:
Animate.css——CSS动画的跨浏览器库。像一件简单的事情一样容易使用。
Canvas:
-
EaselJS——EaselJS是一个用于在HTML5中构建高性能交互式2D内容的库。
-
Fabric.js——支持动画的JavaScript画布库。
-
Paper.js——矢量图形脚本的瑞士军刀。
-
Scriptgrapher——使用HTML5 Canvas移植到JavaScript和浏览器。
-
Pixijs——使用最快、最灵活的2D WebGL渲染创建精美的数字内容。
工作实践
动画帧 ——> 代码 & 设计文件 ——> 代码的转换
-
需要完全前端自己开发 使用已经封装好的动画库,从开发成本和体验角度出发进行取舍。
-
设计同学不是很有空 清晰度,图片格式可以自己指定,动画尽量给出示意或者相似案例参考。需要索要精灵资源、资源需要帮忙压缩。
-
设计资源充足 要求设计导出
lottie
格式文件。
Lottie是可用于Android,IOS,Web和Windows的库,通过Bodymovin解析AE动画,并导出可在移动端和web端渲染动画的json文件。
动画的优化
《让界面动画更自然》
-
性能角度
页面渲染
的一般过程为JS > CSS > 计算样式 > 布局 > 绘制 > 渲染层合并。
其中,
Layout(重排)和Paint(重绘)
是整个环节中最为耗时的两环,所以尽量避免这两个环节。最理想的渲染流水线是没有布局和绘制环节,只需要做渲染层的合并即可。
在实际应用里,最为简单的一个注意点就是,触发动画的开始不要用dispaly:none属性值,因为它会引起Layout、Paint环节,通过切换类名就已经是一种很好的办法。translate属性值来替换top/left/right/bottom的切换,scale属性值替换width/height,opacity替换display/visiblity等等。
CSS3硬件加速又叫做
GPU加速
,是利用GPU进行渲染,减少CPU操作的一种优化方案。由于GPU中的transform等CSS属性不会触发repaint,所以能大大提高网页的性能。
CSS中的以下几个属性能触发硬件加速:
-
transform
-
opacity
-
filter
-
Will-change
如果有一些元素不需要用到上述属性,但是需要触发硬件加速效果,可以使用一些小技巧来诱导浏览器开启硬件加速。
最后
⚽本文带领大家深入了解了前端动画,相信阅读完你一定有了不小的收获~
⚾如果你对这篇文章感兴趣欢迎点赞关注+收藏,更多精彩知识正在等你!😘