前端动画基础笔记

动画的基本原理

  • 什么是动画

    动画是通过 快速连续排列彼此 差异极小连续图像来制造 运动错觉和变化错觉的过程。    ———维基百科
  • 常见的前端动画技术: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 属性引起硬加速

你可能感兴趣的:(前端)