动画的基本原理
-
什么是动画
动画是通过 疾速间断排列 彼此 差别极小 的间断图像 来制作 静止错觉和变动错觉的过程。———维基百科
- 常见的前端动画技术:Sprite 动画、CSS 动画、JS 动画、SVG 动画和 WebGL 动画
- 动画按利用分类:UI 动画、基于 WebGL 的游戏动画和动画数据可视化
-
计算机动画原理
-
计算机图形学:计算机视觉的根底,涵盖点、线、面、体、场的数学构造方法
- 几何和图形数据的输出、存储和压缩
- 形容纹理、曲线、光影等算法
- 物体图形的数据输入(图形接口、动画技术),硬件和图形的交互技术
- 图形开发软件的相干技术标准
- 计算机动画:计算机图形学的分支,次要蕴含 2D、3D 动画
- 无论动画如许简略,始终须要定义两个根本状态即开始状态和完结状态,有了这两个状态能力定义插值状态从而填补两者之间的空白
- 帧:间断变换的多张画面,其中的每一幅画面都是一帧
- 帧率:用于度量肯定时间段内的帧数,通常的测量单位是 FPS(frame per second)
- 帧率与人眼:个别每秒 10 ~ 12 帧人会认为画面是连贯的,这个景象称作视觉暂留。对于一些动画来说低于 30FPS 会感觉到显著卡顿,目前支流的屏幕、显示器输入为 60FPS,成果显著晦涩
- 空白的补全形式有两种:补间动画(关键帧)和逐帧动画
-
前端动画分类
-
CSS 动画
-
CSS animation 是常见的 CSS 动画实现形式
- animation 是 animation-name、animation-duration、animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-fill-mode、animation-play-state 属性的一个简写属性模式
- animation-name 属性指定利用的一系列动画,每个名称代表一个由 @keyframes 定义的动画序列
- animation-duration 属性指定一个动画周期的时长
-
CSS 实现补间动画(Transition API、Keyframe)
- Transition API(过渡动画):DOM 加载实现或 class 发生变化时触发
- keyframe 实现动画:和 transition 相比,关键帧 keyframes 能够管制动画序列的两头步骤
- sprite 实现 CSS 逐帧动画
-
CSS 动画特点:
- 长处:简略、高效、申明式的、不依赖于主线程,采纳硬件加速(GPU);浏览器会对 CSS3 动画做优化,性能上有劣势
- 毛病:不能动静批改或定义动画内容,不同的动画无奈实现同步,多个动画彼此无奈重叠,局部动画无奈实现
- 实用场景:简略的 H5 流动 / 宣传页面
- 举荐库:animation.css、shake.css 等
-
-
SVG 动画
- SVG 是基于 XML 的矢量图形描述语言,它能够和 CSS 和 JavaScript 较好地配合,实现 SVG 动画通常有三种形式:SMIL(Synchronized Multimedia Integration Language 同步多媒体集成语言)、JavaScript、CSS
- 应用 JavaScript 实现 SVG 动画的类库有 snap.js、anime.js 和 HTML 原生的 Web Animation
-
SVG 动画特点:
- 长处:通过矢量元素实现动画,不同屏幕下均可取得较好的清晰度,能够实现一些非凡的成果:描字、形变和墨水扩散等
- 毛病:应用形式较为简单,过多应用可能会带来性能问题
-
JavaScript 动画
- JavaScript 能够实现简单的动画,也能够操作 canvas 动画 API 上进行绘制
-
JavaScript 动画特点:
- 长处:应用灵便,相较 CSS 容易做到两个以上的状态转化
- 毛病:应用到 JS 运行时,调优方面不如 CSS 简略,对于性能和兼容性较差的浏览器 CSS 能够做到优雅降级,而 JS 须要额定代码兼容
-
如何抉择
- 为 UI 元素采纳较小的独立状态时应用 CSS
- 在须要对动画进行大量管制时,应用 JavaScript
- 在特定场景下能够应用 SVG,能够应用 CSS 或 JS 操作 SVG 变动
实现前端动画
-
JavaScript 动画封装函数
- JavaScript 动画应该通过 requestAnimationFrame 内置函数,容许设置回调函数以在浏览器筹备重绘时允行,当页面在后盾时没有产生重绘,回调不会运行,动画将被暂停且不会耗费资源
- JavaScript 实现动画不倡议应用 setTimeout 和 setInterval
- JavaScript 执行动画的核心思想:$Δr = ΔvΔt$,r 是间隔,v 是速度,t 是工夫
-
JavaScript 动画实现代码:
/** * 参数阐明:draw 绘制函数 easing 缓动函数 duration 持续时间 @returns 返回一个 Promise 对象,是因为动画能够是间断的,反对通过 then 函数或 await 进行顺序调用 */ function animate({easing, draw, duration}) { // 动画开始的工夫戳 // 不应用 new Date.now() 因为 performance.now()会以恒定速度自增,准确到微秒级别,不易被篡改 let start = performance.now(); return new Promise(resolve => {requestAnimationFrame(function animate(time) {let timeFraction = (time - start) / duration; if (timeFraction > 1) timeFraction = 1; let progress = easing(timeFraction); draw(progress); if (timeFraction < 1) {requestAnimationFrame(animate); } else {resolve(); } }); }); }
-
draw 绘制函数
const ball = document.querySelector('.ball'); const draw = (progress) => {ball.style.transform = `translate(${progress}px, 0)`; }
-
easing 缓动函数
easing(timeFraction) {return timeFraction ** 2;}
相干实际
-
动画资源
- SVG:Snap.svg – 古代 SVG 图形的 JavaScript 库、Svg.js – 用于操作和动画 SVG 的轻量级库
- JavaScript:GSAP – JavaScript 动画库、TweenJs – 一个简略但功能强大的 JavaScript 补间 / 动画库。CreateJS 库套件的一部分、Velocity – 减速的 JavaScript 动画
- CSS:Animate.css – CSS 动画的跨浏览器库。像一件简略的事件一样容易应用
- canvas:EaselJs – 是一个用于在 HTML5 中构建高性能交互式 2D 内容的库、Fabric.js – 反对动画的 JavaScript 画布库、Pixijs – 应用最快、最灵便的 2D WebGL 渲染器创立精美的数字内容
-
动画的优化
- 性能角度:页面渲染的个别过程为 JS > CSS > 计算款式 > 布局 > 绘制 > 渲染层合并,即 JavaScript > Style > Layout > Paint > Composite
- 其中,Layout(重排)和 Paint(重绘)是整个环节中最为耗时的两环,所以咱们尽量避免这两个环节,从性能方面思考,最现实的渲染流水线是没有布局和绘制环节的,只须要做渲染层的合并即可(重排必然重绘,重绘不肯定重排)。在理论的利用里,最为简略的一个留神点就是,触发动画的开始不要用 display: none 属性值,因为它会引起 Layout、Paint 环节,通过切换类名就曾经是一种很好的方法
-
另外一些优化计划:
- translate 属性值来替换 top/left/right/bottom 的切换
- scale 属性值替换 width/height
- opacity 属性替换 display/visibility
- CSS3 硬减速(GPU 减速):应用 transform、opacity、filter、will-change 属性引起硬减速