动画

定义

  • 由许多静止的画面(帧)
  • 以一定的速度(如每秒 30 张)连续播放时
  • 肉眼因视觉残像产生错觉
  • 而误以为是活动的画面

概念

  • 帧:每个静止的画面都叫帧
  • 播放速度:每秒 24 帧(影视)或者每秒 30 帧(游戏)

一个最简单的例子

将 div 从左往右移动

原理

  • 每过一段时间(用 setinterval 做到)
  • 将 div 移动一小段距离
  • 直到移动到目标地点

注意性能

  • 绿色表示重新绘制(repaint)了
  • CSS 渲染过程依次包含 布局、绘制、合成
  • 其中布局和绘制可能被忽略

前端高手不用 left 做动画

用transform (变形)

原理

  • transform: translateX(0 => 300px)
  • 直接修改会被合成,需要等一会修改
  • transition 过渡属性可以自动脑补中间帧

注意性能

  • 没有 repaint (重新绘制)
  • 比改 left 性能好

浏览器的渲染原理

Google 团队写的文章(右上角中文)

浏览器渲染过程

步骤

  • 根据 HTML 构建 HTML 树(DOM
  • 根据 CSS 构建 CSS 树(CSSOM
  • 将两棵树合并成一棵渲染树(render tree
  • Layout 布局(文档流、盒模型、计算大小和位置)
  • Paint 绘制(把边框颜色、文字颜色、阴影等画出来)
  • Compose 合成(根据层叠关系展示画面)
    1

如何更新样式

一般我们用 JS 来更新样式

  • 比如 div.stlye.background= 'red'
  • 比如 div.stlye.display = 'none'
  • 比如 div.classList.add('red')
  • 比如 div.remove() 直接删掉节点

那么这些方法有什么不同吗?

  • 有三种不同的渲染方式
  • 详情看下一张 PPT

三种更新方式

2

  1. 第一种, 全走
    • div.remove() 会触发当前消失,其他元素 relayout
  2. 第二种,跳过 layout
  3. 第三种,跳过 layout 和 paint
    • 改变 transform, 只需 composite
    • 注意必须全屏查看效果,在 iframe 里看有问题

每一个属性到底会触发哪一种流程

CSS 动画优化

没什么技术含量

JS 优化

  • 使用 requestAnimationFrame 代替 setTimeoutsetInterval

CSS 优化

  • 使用 will-changetranslate

没错

  • 完全就是死记硬背

transform 完整介绍

  • 你不知道去看 MDN 吗?
    • 他们充钱了
      • 哦,充钱了啊,那我还是讲解一下吧

transform

四个常用功能
经验
  • 一般都需要配合 transition 过渡
  • inline 元素不支持 transform ,需要先变成 block

transformtranslate

  • 移动
常用写法
  • translateX(<length-percentage>)
  • translateY(<length-percentage>)
  • translate(<length-percentage>,<length-percentage>?)
  • translateZ(<length>) 且父容器 perspective
  • translate3d(x, y, z)
  • JSBin 演示
经验

transformscale

  • 放大缩小
常用写法
  • scaleX(<number>)
  • scaleY(<number>)
  • scale(<number>, <number>?)
    • ? 表示此属性可以不写
  • JSBin 演示
经验
  • 用的较少,因为容易出现模糊

transformrotate

  • 旋转
  • deg 度数 单位
常用写法
经验
  • 一般用于 360 度旋转制作 loading
  • 用到时再搜索 rotate MDN 看文档

transformskew

  • 倾斜
常用写法
  • skewX([ <angle> | <zero> ])
  • skewY([ <angle> | <zero> ])
  • skew([ <angle> | <zero> ], [ <angle> | <zero> ]?)
  • JSBin 演示
经验
  • 用得较少
  • 用到时再搜 skew MDN 文档

transform 多重效果

组合使用

  • transform: scale(0.5) translate(-100%, 100%);
  • transform: none; 取消所有

实践

跳动的心,先给大家

心得

  • CSS 需要你有想象力,而不是逻辑
  • CSS 给出的属性都很简单,但是可以组合得很复杂

transition (过渡)

作用

  • 补充中间帧

语法

  • transition: 属性名 时长 过渡方式 延迟
    • 属性名就是上下左右
    • 时长可以写秒 也可以写毫秒
    • 过渡方式有很多种,详情见 MDN 上面的数学曲线
    • 延迟就是停多长时间再执行,也可以 ms
  • transition: left 200ms linear
  • 可以用逗号分隔两个不同的属性
  • transition: left 200ms, top 400ms
  • 可以用 all 代表所有属性
  • transition: all 200ms
  • 过渡方式有: linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier | step-start | step-end | steps, 具体含义 要靠数学知识

注意:并不是所有属性都能过渡

  • display: none => block 没法过渡
  • 一般改成 visibility: hidden => visible (不要问为什么)
    • displayvisibility 的区别自己搜一下
    • opacity 可以改变透明度过渡,但是一般在动画完成之后 remove
    • ontransitionend
  • background 颜色可以过渡吗?
    • 任何颜色都可以
  • opacity 透明度可以过渡吗?
    • 可以,只要有规律就可以过渡的

过渡必须要有起始

  • 一般只有一次动画,或者两次
  • 比如 hover 和非 hover 状态的过渡

除了起始,还可以有中间点

两种方法
  1. 使用两字 transform
  2. 使用 animation
animation
@keyframes 完整语法

标准写法

1

animation

缩写语法

  • animation: 时长 | 过渡方式 | 延迟 | 次数 | 方向 |填充模式 | 是否暂停 | 动画名;
  • 时长:1s 或者 1000ms
  • 过渡方式:跟 transition 取值一样,如 linear
  • 次数:3 或者 2.4 或者 infinite
    • infinite 无线的
  • 方向: reverse | alternate | alternate-reverse
    • 反向 交替 交替反向
  • 填充模式:none | forwards | backwards | both
  • 是否暂停:paused | running
  • 以上所有属性都有对应的单独属性