动画的基本原理
什么是动画
动画是通过疾速间断排列彼此差别极小的间断图像来制作静止错觉和变动错觉的过程。 ———维基百科
- 常见的前端动画技术: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 = vt$ ,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 属性引起硬减速