1.动画

1.1.定义

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

1.2.概念

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

1.3.一个简单的例子

  • 将 div 从左往右移动

jsbin示例1(用 left

  • 原理

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

  • 注意性能

绿色表示重新绘制(repaint)了
CSS 渲染过程依次包含布局、绘制、合成
其中布局和绘制后面有详细的

1.4.前端高手不用 left 做动画

  • transform (变形)

jsbin示例

  • 原理

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

  • 注意性能

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

2.浏览器渲染原理

2.1.参考文章

(1)Google 团队写的文章

(2)查看 CSS 各属性触发什么

  • Csstriggers.com

    2.2.浏览器渲染过程

    (1)步骤:

  • 根据 HTML 构建 HTML 树(DOM)

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

    (2)三棵树(渲染树构建、布局及绘制

    image.png

    2.3.如何更新样式

    (1)一般用 JS 来更新样式

  • 如 div.style.background = ‘red’ 加样式,背景变红

  • 如 div.style.display = ‘none’ 让一个 div 不见
  • 如 div.classList.add(‘red’) div 加一个类(一般都是加类,加类更方便,而不是去加样式)
  • 如 div.remove()直接删掉节点

    (2)三种更新方式(渲染性能

    image.png

  • 第一种,全走

div.remove() 会触发当前消失,其他元素 relayout

  • 第二种,跳过 layout

改变背景颜色,直接 repaint+composite

  • 第三种,跳过 layoutpaint

改变 transform,只需 composite
注意必须全屏查看效果,在 iframe 里看有问题

  • 每个属性触发什么流程 https://csstriggers.com/

    浏览器运行 JS 时看效果,出现背景色(绿色)表示重新绘制了

    开发者工具(右键点检查)>控制台(按 Esc)>Rendering>Patint flashing(勾选)>运行 JS(单独放一个网页看更清楚)
    image.png

    2.4.CSS 动画优化

    渲染性能 答案都在Google写的文章里,完全死记硬背,如:

  • JS 优化

使用 requestAnimationFrame 代替 setTimeoutsetInterval

  • CSS 优化

使用 will-changetranslate

3.transform 完整介绍

MDN 文档 自己一个个的去试就可以

3.1.四个常用功能

  • 位移 translate(用的最多)
  • 缩放 scale
  • 旋转 rotate
  • 倾斜 skew

    经验

  • 一般都需要配合 transition 过渡

  • inline 元素不支持 transform,需要先变成 block

    3.1.1.transform:translate 位移

    常用写法

    JSBin

    1. translateX(<lenght-percentage>)
    2. translateY(<lenght-percentage>)
    3. translate(<lenght-percentage>,<lenght-percentage>?)/*加 ? 表示可以省略*/
    4. translateZ(<lenght>) /*近大远小*/
    5. translate3d(x,y,z)

    经验

  • 学会看懂 MDN 的语法示例

  • translate(-50%,-50%) 可做绝对定位元素的居中(请记住)

    1. left: 50%;right: 50%;
    2. transform: translate(-50%,-50%);
    3. /* transform: translateX(-50%) translateY(-50%); */

    3.1.2.transform:scale 缩放

    常用写法

    1. scaleX(<number>)
    2. scaleY(<number>)
    3. scale(<number>,<number>?)/*例如transform: scale(1.5,0.5);*/

    示例

    经验

  • 容易出现模糊

    3.1.3.transform:rotate 旋转

    常用写法

    1. rotate([<angle>|<zero>])/*默认是沿着z轴转动*/
    2. rotateZ([<angle>|<zero>])
    3. rotateX([<angle>|<zero>])/*看着会变矮*/
    4. rotateY([<angle>|<zero>])/*看着会变窄*/

    rotate3d 太复杂 JSBin
    CSS 角度单位介绍

    经验

  • 一般用于 360 度旋转制作 loading

  • 用到时再搜索 rotate MDN 看文档

    3.1.4.transform:skew 倾斜

    常用写法

    1. skewX([<angle>|<zero>])/*左右倾斜*/
    2. skewY([<angle>|<zero>])/*上下倾斜*/
    3. skew([<angle>|<zero>],[<angle>|<zero>]?)/*默认是X轴*/

    示例

    经验

  • 用到较少,用到时再搜索 skew MDN 看文档

    3.1.5.transform 多重效果

    组合使用

    示例

    1. transform: scale(0.5) translate(-100%,-100%);
    1. transform: none;/*取消所有,不写 transform 也是取消所有*/

    3.2.实践

    跳动的心1—使用 transform、transition 和 :hover

    一个心想象成上面两个半圆和下面一个正方形

    心得

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

    3.3.transition 过渡

    题外话:变形金刚-transformers
    image.png

    过渡方式具体含义

    使用较多的:

  • linear-线性,匀速变化

  • ease-非线性

简单示例

3.3.1.并不是所有属性都能过渡

总结:只要能找到过渡规律的就可以过渡,找不到过渡规律就不能过渡

3.3.2.过渡必须要有始终

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

3.3.3.过渡除了始终还有中间点处理方法

方法一:使用两次 transform

  • .a === transform ===>.b
  • .b=== transform ===>.c
  • 如何知道到了中间点:用 setTimeout 或者监听 transitionend 事件
  • 示例

    方法二:使用 animation

    示例

    @keyframes 完整语法(声明关键帧)

    标准写法:@keyframes MDN

  • 一种写法是 from-开始=0% to-结束=100%

    1. @keyframes xxx{
    2. from {
    3. transform: translateX(0%);
    4. }
    5. to {
    6. transform: translateX(100%);
    7. }
    8. }
  • 另外一种百分数

    1. @keyframes xxx{
    2. 0% { top: 0; }
    3. 50% { top: 30px; left: 20px; }
    4. 50% { top: 10px; }
    5. 100% { top: 0; }
    6. }

    animation

    缩写语法:
    animation:时长 | 动画名 | 过渡方式 | 延迟 | 次数 | 方向 | 填充模式 | 是否暂停 (中间空格隔开)
    默认值:
    单个属性:

  • 时长(animation-duration):1s/1000ms

  • 过渡方式(animation-timing-function):如 linear / ease
  • 延迟(animation-delay):s/ms
  • 次数(animation-iteration-count):2 或 3.6或 infinite(表示动画永远重复)
  • 方向(animation-direction):normal(正)| reverse(反)| alternate (正+反)| alternate-reverse(反+正)
  • 填充模式(animation-fill-mode):none | forwards(停在最后一个关键帧) | backwards(触碰目标回到第一个关键帧) | both
  • 是否暂停(animation-play-state):paused | running

跳动的心2—使用 animation