CSS动画

677 阅读2分钟

动画的原理

定义

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

概念

  • 帧:每个静止的画面都叫做帧

  • 播放速度:美妙24帧(影视)或每秒30帧(游戏)

例一:用left做移动

  • 原理:每过一段时间,将div移动一小段距离,知道移动到目标地点

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

例二:用transform做移动

  • 原理:

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

  • 注意性能:left < transform < repaint(重新绘制)

浏览器渲染原理

Google:

渲染树构建、布局及绘制

渲染性能

使用transform来实现动画

查看CSS各属性触发什么

CSSTriggers.com

1:Google 2:firefox 3:safari 4:ie

浏览器渲染过程

步骤:

  1. 根据HTML构建HTML树(DOM)

  2. 根据CSS构建CSS树(CSSOM)

  3. 将两棵树合并成一颗渲染树(render tree)

  4. Layout布局(文档流、盒模型、计算大小和位置)

  5. Paint绘制(把边框颜色、文字颜色、阴影等画出来

  6. Composite合成(根据层叠关系展示画面)

三棵树

如何更新样式

一般用JS来更新样式

比如 div.style.background = 'red'

比如 div.styyle.display = 'none'

比如 div.classList.add('red')

比如 div.remove()直接删掉节点

三种更新方式

第一种,全走:

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

第二种,跳过layout

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

第三种,跳过layout和paint

改变transform,只需要composite

CSS动画优化

Google渲染性能

使用requestAnimationFrame代替setTimeout或setInterval

CSS优化

使用will-change或translate

transform

MDN

四个常用功能

位移translate

常用写法
  • translateX(<length-percentage>)

  • translateY(<length-percentage>)

  • translate(<length-percentage>,<length-percentage>?)

  • translateZ(<length>)且父容器perspective

  • translate3d(x,y,z)

经验

translate(-50%,-50%)可以做绝对定位元素的居中

缩放scale

常用写法

scaleX(<number>)

scaleY(<number>)

scaleZ(<number>,<number>?)

经验:

使用容易出现模糊

旋转rotate

常用写法

rotate([<angle>|<zero>])

默认是按z轴旋转

rotateZ([<angle>|<zero>])

rotateX([<angle>|<zero>])

rotateY([<angle>|<zero>])

rotate3d

经验

一般用于360度旋转制作loading

倾斜skew

常用写法

skewX([<angle>|<zero>])

skewY([<angle>|<zero>])

skew([<angle>|<zero>],[<angle>]|<zero>?)

transform多重效果

组合使用

transfrom: scale(0.5) translate (-100%,-100%)

transform: none;取消所有

经验

  • 一般都需要配合transition过渡

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

跳动的心

transition

作用

补充中间帧

语法

transition: 属性名 时长 过渡方式 延迟(

可用逗号分隔两个不同属性

可用all代表所有属性

)

transition: left 200ms linear 3s,top 2s;或transition: all 1s;

过渡方式有: linear

线性,匀速

| ease

缓冲

| ease-in

淡入

| ease-out

淡出

| ease-in-out

淡入和淡出

| cubic-bezier | step-start | step-end | steps

注意

并不是所有属性都能过渡

display:none => block 不能过渡

一般改成 visibility: hidden => visible

background、opacity也可以过渡

过渡必须要有起始

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

使用两次transform

.a === transform ===> .b

.b === transform ===> .c

通过 setTimeout 或者监听 transitioned 事件

animation

@keyframes 完整语法

写法一

@keyframes slidein{    from{        transform: translateX(0%);    }    to{        transform: translateX(100%);    }}

写法二

@keyframes identifier{    0% { top: 0; left: 0; }    30%{ top: 50px; }    68% , 72% { left: 50px; }    100%{ top: 100px; left: 100px; }}

animation 缩写语法

animation: 时长 | 过渡方式 | 延迟 | 次数 | 方向 | 填充模式 | 是否暂停 | 动画名;

时长: 1s或者1000ms

过渡方式: 和transition取值一样,例如linear

次数: 整数或者小数或者infinite

方向:reverse | alternate | alternate-reverse

填充模式: none | forwards | backwards | both

是否暂停: paused | running

以上所有属性都有对应的单独属性

若指定单一属性,需用下面语法:

The animation shorthand CSS property applies an animation between styles. It is a shorthand for animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, and animation-play-state.

跳动的心