笔记 - CSS动画

动画:24帧
游戏:30帧
现在大部分显示器的最低刷新频率为60Hz,即每秒60帧。

setInterval()制作动画

setInterval()可被用于实现css动画,使用position: relative并改变其属性(比如left)。
e.g.
html

css

#demo {
  width: 100px;
  height: 100px;
  border: 1px solid red;
  position: relative;
  left:0;
}

js

var n=1;
var id = setInterval(() => {
  if (n<=200){
    demo.style.left=n+'px';
    n=n+1;
  }
  else{
    clearInterval(id);
  }
}, 1000/60);



tips:关于停止setInterval()

setInterval()在窗口和工作接口上提供的setInterval()方法重复调用函数或执行代码片段,每次调用之间有固定的时间延迟。它返回一个时间间隔ID,该ID唯一地标识时间间隔,因此您可以稍后通过调用clearInterval()来删除它。

因此可利用clearInterval()清除唯一的ID停止setInterval()

var id = setInterval(() => {
  if (condition){
    statements ...
  }
  else{
    clearInterval(id)
  }
}, 1000/60)


tips:paint flashing观察性能
develop tool中打开rendering 勾上Paint flashing,能观察到CSS是否重新渲染

transform做动画

html

css

#demo {
  width: 100px;
  height: 100px;
  border: 1px solid red;
  transition: all is linear;
}

/* 设置transform动画 */
#demo.end {
  transform: translateX(200px);
}

js

setTimeout(()=>{
  demo.classList.add('end');
}, 3000);

transform制作的动画图形并非缓慢移动,而是急速闪现在目标位置。
transform触发的css渲染次数远远少于setInterval()

浏览器渲染原理

  1. 构建 DOM - HTML tree
  2. 构建 CSSOM - CSS tree
  3. 合并 DOM, CSSOM -> Render tree
  4. 根据渲染树构成 Layout (文档流,盒模型,计算大小、位置),形成线框。
  5. Paint, 绘制边框颜色,文字颜色,阴影等。
  6. Compose 根据层叠关系合成,展示画面。

执行js脚本 -> 构建style -> 形成layout -> 绘制页面 -> 合成最终画面

渲染的三种更新方式中,layout和paint可能会被省略。根据颜色和位置大小的改编决定哪种会被省略。

  • 完全更新:对布局位置的修改会触发(div.remove()),元素relayout
  • 跳过layout更新:修改背景颜色会触发,repaint + composite
  • 跳过layout + paint更新:元素位移(transform)会触发,composite。需要全屏查看,iframe有问题。

tips: 查看元素渲染
csstrigger.com 提供了所有css元素在不同浏览器上的渲染过程。

CSS优化

  • 渲染性能:Google开发者文档https://developers.google.com/web/fundamentals/performance/rendering
  • JS优化:使用 requestAnimationFrame()替代 setTimeout() 或者 setInterval()
  • CSS优化:使用 will-change 或者 translate属性

transform 用法

MDN文档有语法格式 https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform
transform属性均可组合使用。比如放大的同时位移。

translate 位移

X: 横轴
Y: 纵轴
Z: 从显示器到屏幕的距离。通过perspective属性设置视点。

transform: translate3d(x, y, z)
transform: translateX(x_value) translateY(y_value)
transform: translate(x_value, y_value)

/* 绝对居中的一种写法(IE不支持) */
top: 50%;
left: 50%;
transform: translate(-50%, -50%)
scale 缩放

倍数缩放

  • transform: scale(1.5) 整体放大1.5倍
  • scaleX(x_value), scaleY(y_value), scaleZ(z_value) X, Y, Z 按比缩放
  • scale3d(x_value, y_value, z_value) X, Y, Z三轴各自按比缩放
  • transform: scale(x_value, y_value) X轴,Y轴各自缩放
  • transform: scale(x_value, y_value, z_value) 相当于于scale3d函数,X, Y, Z三轴各自按比缩放
rotate 旋转
  • transform: rotate( deg | turn | rad )
  • transform: = rotate3d(x_value, y_value, z_value)
  • transform: rotateX( x_value )
  • transform: rotateY( y_value )
  • transform: rotateZ( z_value )
skew 倾斜
  • transform: skew(deg)
    用法基本同上,xyz三轴均可。

transition 过渡

添加中间帧
transition: 属性 时长 过渡方式 延迟

  • all可以代表所有属性
  • 过渡方式: linear, ease, ease-in, ease-out, ease-in-out, cubic-bezier, step-start, step-end, steps
  • background颜色可以过渡
  • opacity透明度可以过渡
    不适用的情况:
  • display: block => display: none 不显示则无结果。虽然看不见但位置还在。如果想要消失效果,使用visibility: visible => visibility: hidden

animation

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

  • 百分数
#example{
  animation: time forwards identifier;
}
@keyframes identifier {
  0% { attributes;}
  66% { attributes;}
  100% { attributes;}
}
  • from to
#example{
  animation: time forwards identifier;
}
@keyframes identifier {
from { attributes;}
66% { attributes;}
to { attributes;}
}

forwards: 属于填充模式 让动画停在最后一帧。

回流 (Reflow)

当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。

会导致回流的操作:

  • 页面首次渲染
  • 浏览器窗口大小发生改变
  • 元素尺寸或位置发生改变
    -元素内容变化(文字数量或图片大小等等)
  • 元素字体大小变化
  • 添加或者删除可见的DOM元素
  • 激活CSS伪类(例如::hover)
  • 查询某些属性或调用某些方法

一些常用且会导致回流的属性和方法:
clientWidth、clientHeight、clientTop、clientLeft
offsetWidth、offsetHeight、offsetTop、offsetLeft
scrollWidth、scrollHeight、scrollTop、scrollLeft
scrollIntoView()、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()

重绘 (Repaint)

当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
性能影响
回流(reflow)比重绘(repaint)的代价要更高。
有时即使仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流。
现代浏览器会对频繁的回流或重绘操作进行优化:
浏览器会维护一个队列,把所有引起回流和重绘的操作放入队列中,如果队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样可以把多次回流和重绘变成一次。
当你访问以下属性或方法时,浏览器会立刻清空队列:

clientWidth、clientHeight、clientTop、clientLeft
offsetWidth、offsetHeight、offsetTop、offsetLeft
scrollWidth、scrollHeight、scrollTop、scrollLeft
width、height
getComputedStyle()
getBoundingClientRect()
因为队列中可能会有影响到这些属性或方法返回值的操作,即使你希望获取的信息与队列中操作引发的改变无关,浏览器也会强行清空队列,确保你拿到的值是最精确的。

Reflow & Repaint 部分 引用自:https://juejin.cn/post/6844903569087266823

一颗小红心:

  • transform, transition and hover
    http://js.jirengu.com/hogucoluqo/1/edit?html,css,output
  • animation
    http://js.jirengu.com/mepakaraco/1/edit?html,css,output

你可能感兴趣的:(笔记 - CSS动画)