CSS动画

82 阅读4分钟

动画是由许多静止的画面(帧),以一定的速度(如每秒30张)连续播放时,内容因视觉残像产生错觉,而误以为是活动的画面

动画的概念:每个静止的画面都叫做帧,比如每秒24帧电影或每秒30帧游戏

// setInterval() 当你使用需要结束的时候用 clearInterval(id)
var id = setInerval(()=>{
    if(){}
    else{ clearInterval(id) 
}, 1000)

如何查看这个动画绘制过程,可以打开这个看

image.png 浏览器Rendering-paint flashing 可开启

性能

left

  • 绿色表示repaint(重新绘制)
  • css渲染过程依次包含布局、绘制、合成、其中布局和绘制有可能被省略

transform

  • 并没有repaint(重新绘制)
  • 比改left性能好

浏览器渲染原理

渲染过程

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

更新样式方法

一般使用JS来更新样式

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

以上方法的解析

  1. js/css>样式>布局(layout)>绘制(paint)>合成(compsite)

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

  2. js/css>样式>绘制(paint)>合成(compsite)

    改变背景颜色,直接rapaint+compsite

  3. js/css>样式>合成(compsite)

    改变transform,只需compsite

如何查看那些属性执行了那些方式

csstriggers

优化

渲染性能 | Web | Google Developers

  • css优化:left变成transform 或 使用will-change或translate

  • js优化:使用requestAnimationFrame代替setTimeout或setInterval

CSS动画方法( transition 和 animation )

transform

四个常用功能

  • translate 位移

    • translateX/Y/Z() X是X轴变化,Y是Y轴变化,Z是垂直于视点,且需父容器 添加perspective(试点或景深)
    • translate(X, Y)
    • translate3d(X, Y, Z)
  • scale 缩放:用的较少,因为容易模糊

    • scaleX/Y() X是X轴变化,Y是Y轴变化
    • translate(X, Y)
  • rotate 旋转

    • rotate([<angle>|<zero>])
    • rotateZ/X/Y([ | ])
    • rotate3D 太复杂,详细请查资料
  • skew 倾斜

    • rotate(X, Y)
    • rotateX/Y([ | ])
  • 组合使用

    • transform: scale(0.5) translate(-100%,-100%);
    • transform: none;取消所有

经验

  • 一般都需要配合transition过渡
  • inline 元素不支持 transform,需要先变成block
  • 做绝对定位元素的水平居中
父类{ 
    border: 1px solid black;
    position: relative;
    height: 500px; 
}
子类{
    width: 100px;
    height: 100px;
    border: 1px solid red;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

transition 过渡

作用:补充中间帧

语法

  • transition: 属性名 时长(s/ms) 过度方式 延迟
  • transition: left 200ms linear
  • 可以用逗号分隔两个不同属性
  • transition: left 200ms,top 400ms
  • 可以用all代表所以属性
  • transition: all 200ms
  • 过度方式:
    • linear:线性,匀速
    • ease:缓动
    • ease-in:淡入
    • ease-out:淡出
    • ease-in-out
    • cubic-bezier:曲线
    • step-start
    • step-end
    • steps: 步数,可以做动态图

并不是所有属性都能过渡

  • display: none => block 没法过渡
  • 一般改成visibility: hidden => visible,虽然不见了,但是还是占元素(不要问为什么)
  • display 和 visibility 的区别自己搜一下
  • background 颜色可以过渡嘛?有过渡效果的
  • opacity透明度可以过渡嘛?可以,但不推荐

过渡必须要有起始:一般只有一次或两次动画,比如hover或非hover状态过渡

display 和 visibility 的区别

  1. display:none 不显示对应的元素,在文档布局中不再分配空间(回流+重绘),简单的意思是说只是把元素隐藏起来
  2. visibility:hidden 隐藏对应元素,在文档布局中仍保留原来的空间(重绘),简单的意思是说隐藏元素不占文档流

属性值

  • display:请看我这篇文章
  • visibility:visible; 元素可见,默认值 hidden; 隐藏的元素仍然占据文档流 collapse; 只对table对象起作用,用在其他元素中表示隐藏 inherit; 继承其父级样式

animation

animation: 动画名称(不一定写到第一位也可以) 时长(s/ms)
    过渡方式 延迟 次数 方向 填充模式 是否暂停;
animation-duration(时长):1s或者1000ms
animation-timing-function(过渡方式):跟transition 取值一样
animation-delay(延迟): 1s或者1000ms
animation-iteration-count(次数):3或者infinite(无限次)
animation-direction(方向):
    reverse(反向) | alternate(交替) | alternate-reverse(从结尾开始)
animation-fill-mode(填充模式):
    none | forwards(保留最后一帧) | backwards | both
animation-play-state(是否暂停): paused(暂停) | running(恢复)
@keyframes 动画名称 { 0%{} 100%{}(百分数写法) || from{} to {}(form to写法) }