1.【CSS 动画基础】

动画原理

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

动画的渲染性能

  • 在开发者工具中打开 Rendering 面板,勾选 'Paint falshing' 选项,页面上重新绘制(repaint)的地方会变绿;必须全屏查看效果,在 iframe 里看会有问题
  • 使用 setInterval 实现的动画在执行过程中会不停地重新渲染,性能较差
  • 使用 transform 实现的动画在执行过程中重新渲染的次数很少,性能提升很多

浏览器渲染原理

  1. 根据 HTML 构建 HTML 树(DOM)
  2. 根据 CSS 构建 CSS 树(CSSOM),和 DOM 不完全一样
  3. 将两棵树合并成一颗渲染树(Render Tree),就是用户最终看到的树
  4. 进行布局(Layout),将元素定位,设置大小(文档流、盒模型)
  5. 进行绘制(Paint),将边框颜色、文字颜色、阴影等画出来
  6. 进行合成(Compose),根据层叠关系展示画面




swift 放大缩小动画_swift 放大缩小动画


更新样式的方法

  • 一般使用 JS 来更新样式
  • div.style.background = 'red' 设置背景色
  • div.style.display = 'none' 隐藏元素
  • div.classList.add('red') 添加类,最常用,一个类可以包含很多样式
  • div.remove() 删除节点

三种不同的渲染方式

  • 方式1:布局 > 绘制 > 合成,div.remove(),会触发当前元素消失,其他元素 relayout
  • 方式2:绘制 > 合成,例如改变背景色
  • 方式3:只需合成,性能最好,例如 transform
  • 如何知道每个 CSS 属性使用哪种渲染方式:https://csstriggers.com/
  • Chrome 浏览器内核 = Blink
  • Firefox 浏览器内核 = Gecko
  • Safari 浏览器内核 = Webkit
  • edge 浏览器内核 = EdgeHTML


swift 放大缩小动画_css 缩放_02


CSS 动画优化

  • 使用 transform 代替 left
  • 使用 will-change 或 translate 属性
  • 优化 JS:使用 requestAnimationFrame 代替 setTimeout 和 setInterval
  • 绘制通常是性能开销最大的部分,应尽可能避免绘制;除 transform 和 opacity 属性之外,更改任何属性始终都会触发绘制。

2.【transform 变形】

四种常用变形

  • 位移 translate
  • translateX( <length-percentage> ) 横向位移
  • translateY( <length-percentage> ) 纵向位移
  • translateZ( <length> ) Z轴位移,在 3D 视图中才会生效,需要在父元素添加属性 perspective,设置透视图的视点位置
  • translate( x, y ) 二维位移的简写形式
  • translate3d( x, y, z ) 三维位移的简写形式
  • 参数可以是百分数,使用 translate(-50%, -50%) 配合 left:50%; top:50% 可以设置绝对定位元素的居中
  • 缩放 scale
  • scale( <number>, <number>? ) 设置元素缩放比例,1 为原比例
  • 也可使用 scaleX | scaleY 分别设置横/纵向的缩放比例
  • 使用 scale 缩放会导致 border 也变宽/窄,容易出现模糊,因此很少使用
  • 旋转 rotate
  • rotate( [<angle> | <zero>] ) 从12点钟方向顺时针旋转,角度单位 360deg
  • 默认围绕 Z 轴转动,也可以围绕 X 轴或 Y 轴 转动,rotateX | rotateY
  • 一般用于制作 360° 旋转的 loading 图标
  • 倾斜 skew
  • skewX( [<angle> | <zero>] ) 沿 X 轴倾斜,用的较少

经验技巧

  • 动画调试技巧:在开发者工具中选中 transform 属性后的数值,按 ↑ ↓ 可以实时增减数值,按住 shift 可以加大增减幅度
  • 可以添加多个效果,用空格隔开
  • transform: none; 清除所有效果
  • 一般与 transition(过渡)配合使用,产生动画效果 transition: all 1s
  • inline 元素不支持 transform 属性,需要先转换为 block 元素

3.【transition 过渡】

  • 作用是补充中间帧,形成动画效果
  • transition 属性名 时长 过渡方式 延迟
  • 举例:transition: left 200ms linear 3s
  • 过渡方式:linear 线性,匀速变化 | ease 先快后慢,默认 | ease-in 淡入 | ease-out 淡出 | ease-in-out 淡入+淡出 | 等等
  • 可以用逗号分隔两个不同属性:transition: left 200ms, top 400ms
  • 可以用 all 代表所有属性:transition: all 200ms
  • 并不是所有属性都能过渡
  • display: none <==> block 不能过渡
  • 可以使用 visibility: hidden <==> visible 切换元素是否可见
  • opacity: 0 只能让元素看不见,但是位置和大小还在那里,一般需要在动画执行后删除元素 div.addEventListener('transitionend', ()=> { div.remove() })
  • background 也可以过渡,因为是16进制的颜色值
  • 多次过渡动画
  • .a ==> .b .b ==> .c ,使用 div.classList.remove 和 classList.add 改变元素的css类,注意第二次变形要保留第一次变形的状态

4. 【animation 动画】

  • animation: 时长 | 过渡方式 | 延迟 | 次数 | 方向 | 填充模式 | 是否暂停 | 关键帧名
  • 过渡方式:和 transition 取值一样,默认 ease
  • 次数:3 | 2.4 | infinite(无限)
  • 方向:reverse(反向) | alternate(交替) | alternate-reverse
  • 填充模式:none | forwards(停在最后一帧) | backwards | both
  • 是否暂停:paused | running 可以通过 div.style.animationPlayState = 'paused | running' 控制动画暂停、恢复
  • 每个属性都有单独的属性名
  • @keyframes 关键帧的两种语法
@