CSS动画

150 阅读2分钟

浏览器渲染

过程

  1. 根据HTML构建HTML的树

    DOM

  2. 根据CSS构建CSS树

    CSSOM

  3. 将两棵树合并成一颗渲染树

    render tree

  4. Layout布局

    文档流、盒模型、计算大小与位置

  5. Paint绘制 (console->Esc->Rendering->Paint Flashing)

    把边框颜色、文字颜色、阴影都画出来

  6. Compose合成

    根据层叠关系展示画面

利用JS的更新方式

graph LR
A(Javascript)-->B(Style)-->|第一种|C(Layout)-->D(Paint)-->E(Composite)
B(Style)-->|第二种|D(Paint)
B(Style)-->|第三种|E(Composite)
  1. 全走

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

  2. 跳过Layout

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

  3. 跳过Layout和Paint,只需Composite (最佳性能

    改变transform,只需要Composite (必须要全屏查看,在iframe里面查看有问题)

可以通过CSS Triggers查阅CSS的属性会触发哪一种方式

CSS的渲染过程依次包括布局、绘制、合成,其中布局和绘制可省略。

CSS动画优化

  1. JS优化

    使用 requestAnimationFrame代替 setTimeoutsetInterval

  2. CSS优化

    使用 will-changetranslate

transform

常用功能

位移 translate

  • 左右移动transform:translateY(50px)

  • 上下移动 transform:translateX(50px)

  • 纵轴移动

    1. 给父级元素加上 perspective:1000px 视点
    2. 子级元素 transform:translateZ(50px) 子级元素会变化大小
  • 缩写

    transform:translate(右,下)

  • 常用于绝对定位的居中:

    .child{
    	position:absolute;
        left:50%;
        top:50%;
        transform:translate(-50%,-50%)
    }
    .father{
        position:relative;
    }
    

缩放 scale

用得少,容易使图片模糊扭曲

  • 左右缩放 scaleX(1.5)
  • 上下缩放 scaleY(1.5)
  • scale(1.5,0.5)

旋转 rotate

  • transform:rotate(45deg) 默认以垂直屏幕转动
  • transform:rotateX(45deg) 沿着X轴旋转
  • transform:rotateY(45deg) 沿着Y轴旋转

一般用于 loading 的制作

倾斜 skew

正方形变成平行四边形

transform:skew(15deg)

经验:

  1. 组合效果 transform:scale(1.5) rotate(45deg)
  2. 在动画前的元素加 transition:all 1s进行过渡
  3. inline元素不支持 transform,需要变成 block

transition

transition 过渡

主要用于补充中间帧。

语法

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

  • 属性名

    可以是 all

  • 时长 ms s

  • 过渡方式有 linear|ease|ease-in|ease-out|....具体查阅MDN

  • 延迟是指 过了多久执行此过渡

注意:

  1. display:block=>display:none不可以

    visibility:visible=>visibility:hidden 可以

  2. background也可以过渡

animation

打关键帧

.demo {
  width:100px;
  height:100px;
  border:1px solid black;

}
.demo:hover{
   animation:moveName 1s forwards;/*加上forward是停在最后一帧*/
}
@keyframes moveName{
  0%{
  }
  60%{
    transform:translate(50px);
  }
  100%{
    transform:scale(1.5)
  }
}