1 动画的原理

1.1 定义

(1) 动画
动画是由许多静止的画面(帧)组成的, 它以一定的速度(如每秒30帧)连续播放时, 人的眼睛因视觉残象产生错觉,
而误以为是活动的画面.
(2) 帧
每个静止的画面都被称为”帧”.
(3) 播放速度
每秒24帧(影视)或者每秒30帧(游戏).

1.2 div从左往右移动的例子

(1) 原理
每过一段时间, 将div移动一小段距离, 直到移到目的地.
(2) 查看Paint flashing

  • 打开chrome浏览器的开发者工具 > Rendering >勾选Paint flashing.
  • 可以看到浏览器重新绘制页面, 绿色即表示重新绘制(repaint).
  • CSS渲染过程依次包含布局、绘制、合成.
  • 其中布局和绘制可能被省略.

2 浏览器渲染原理

2.1 渲染的步骤

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

三棵树示意图:
image.png

2.2 如何更新样式

一般用JS来更新样式, 比如:

  • div.style.background=”red”
  • div.style.display=”none”
  • div.classList.add(“red”)
  • div.remove( )直接删掉节点

2.3 三种更新方式

(1) 全走, 所有步骤都不落
div.remove( )会触发当前消失, 其他元素 relayout(重新布局).
(2) 跳过 layout
改变背景颜色, 直接repaint + composite .
(3) 跳过 layout 和 paint
进行transform, 只需 composite.
注意: transform必须全屏查看效果, 因为在iframe里看会有问题.

  • 三种更新方式的示意图:

image.png

2.4 CSS各属性触发流程的查询工具

CSS Triggers 网站, 网址 https://csstriggers.com/

2.5 CSS动画优化方法

参考google团队的 Paul Lewis 的文章 Stick to Compositor-Only Properties and Manage Layer Count.

  • 方法一: JS优化

    使用requestAnimationFrame代替setTimeout或setInterval.

  • 方法二: CSS优化

    使用will-change或translate.

3 transform变形

CSS的transform属性作用是位移、缩放、旋转或倾斜给定元素.
transform的四个常用function, 如下

  • translate 位移
  • scale 缩放
  • rotate 旋转
  • skew 倾斜

注意:

  • 一般都需要配合transition(过渡)属性使用.
  • 只对块级元素有效.
  • inline元素不支持transform, 需要先display: block.
  • 涉及3d时, 有时要用到”perspective( )”语法.

语法举例:

  • transform: translateX(20px);
  • transform: scale(5);
  • transform: rotate(45deg);
  • transform: skew(60deg);
  • transform: none;(作用是取消所有transform设置).

使用场景: 跳动的心等.

3.1 translate 位移

(1) 常用写法
translateX( )
translateY( )
translate( , ? )
translateZ( )
translate3d( , , )
(2) 经验:
对一个绝对定位(position: absolute)的元素设置居中, 可以使用这三行代码:

  1. left: 50%;
  2. top: 50%;
  3. transform: translate(-50%, -50%);

3.2 scale 缩放

(1) 常用写法
scale( , ? )
scaleX( )
scaleY( )
(2) 经验
用得较少, 因为容易出现模糊.

3.3 rotate 旋转

(1) 两种rotate

  • roatate可以分为2d旋转和3d旋转.
  • 2d旋转: 元素在二维平面内顺时针旋转或者逆时针旋转.

    1. 2d旋转特点: 角度为正时, 顺时针旋转; 角度为负时, 逆时针旋转.<br /> 默认旋转的中心点是元素的中心点.
  • 3d旋转: 让元素在三维平面内沿着 x轴,y轴,z轴或者自定义轴进行旋转.

    1. 使用"左手准则"判断元素旋转的方向.<br />(2) 2d旋转写法:<br /> rotate( [ <angle> | <zero> ] )<br /> 举例: rotate(45deg); .<br />(3) 3d旋转写法:<br /> rotate3d( <number> , <number> , <number> , [ <angle> | <zero> ] )<br /> rotateX( [ <angle> | <zero> ] )<br /> rotateY( [ <angle> | <zero> ] )<br /> rotateZ( [ <angle> | <zero> ] )<br />(4) rotate的用途<br /> 一般用于360度旋转制作loading.

3.4 skew 倾斜

(1) 常用写法
skew( [ | ] , [ | ]? )
skewX( [ | ] )
skewY( [ | ] )
(2) 经验
用得较少. 用到时再搜索skew MDN文档.

4 transition过渡

  1. transtion的作用是补充中间帧.

4.1 语法

  • transition: 属性名 时长 过渡方式 延迟时长;
  • transition: left 300ms linear;
  • 可以用逗号分隔两个不同属性, 比如 transition: left 400ms, top 300ms.
  • 可以用 all 代表所有属性, 比如 transition: all 1s.
  • 过渡方式有: 其中比较常用的是 linear | ease | ease-in | ease-out | ease-in-out | ;

其中比较少用的是 cubic-bezier | step-start | step-end | steps .

4.2 并不是所有属性都能过渡

(1) display: none → block 无法过渡.
(2) 一般改成visbility: hidden → visible.
(3) background-color 背景色 可以过渡.
(4) opacity 透明度 也能过渡, 不过不建议使用.

4.3 过渡必须要有起始

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

4.4 过渡的中间点

  • 使用两次transform
  • 使用animation

5. animation动画

5.1 animation语法

  • animation: 时长 | 过渡方式 | 延迟 | 次数 | 方向 | 填充模式 | 是否暂停 | 动画名;
  • 时长: 1s 或 1000ms;
  • 过渡方式: 与transition取值相同, 如linear.
  • 次数: 3 或者 2.4 或者 infinite(无限).
  • 方向: reverse | forwards | backwards | both.
  • 是否暂停: paused | running.
  • 以上属性都有对应的单独属性.

    5.2 @keyframes语法

    @keyframes语法有两种写法, 一种是from to, 另一种是百分数.
    语法举例:

image.png

image.png

5.3 让动画停在最后一帧的方法

方法是 animation: forwards.

6 余话

CSS的属性很简单, 但是可以有多种组合, 这样会变得复杂. 为什么CSS不单独出一些很多属性组合在一起而产生效果的属性, 那样程序员就不用写很多代码. 比如出一个属性, 可以生成心形, 或者生成彩虹.
用CSS做图, 需要有想象力.