CSS 动画知识总结

CSS 动画知识总结

一个简单的例子

使用 left 将 div 从左往右移动

原理

每过一段时间(用 setInterval 做到)将 div 移动一小段距离,直到移动到目标地点

注意性能

开发者页面按 ESC调出控制台,点击三个点选择 Rendering,在 Rendering 页面勾选 Paint flashing。勾选完毕后页面上的绿色表示重新绘制 (repaint)。

CSS 渲染过程一次包含布局、绘制、合成。其中布局和绘制有可能被省略。

改进 使用 transform 将 div 从左往右移动

原理

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

性能

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

浏览器渲染原理

参考文章

Google 团队

渲染树构建、布局及绘制

渲染性能

使用 transform 来实现动画

查看 CSS 各属性触发什么

csstriggers.com

浏览器渲染步骤

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

使用 JS 更新样式

比如div.style.background = 'red', div.style.display = 'none', div.classList.add('red'), div.remove()

一般常用的是加类的方式,更方便。

三种更新样式的方式

  1. JS/CSS > Style > Layout > Paint > Composite

    经历全部步骤。 比如 div.remove() 会触发当前元素消失,其他元素重新布局

  2. JS/CSS > Style > Paint > Composite

    跳过 layout,直接 paint + composite。比如说改变背景颜色

  3. JS/CSS > Style > Composite

    跳过 layout 和 paint,只需 composite。(必须全屏查看效果,在 iframe 里看会有问题)。比如说改变 transform

可以在 https://csstriggers.com/ 中查阅各属性触发什么流程

CSS 动画优化

具体查询 Google 文档,需要记住的有

  • JS 优化

    使用 requestAnimationFrame 代替 setTimeout / setInterval

  • CSS 优化

    使用 will-change / translate

transform

经验

  • 一般都会配合 transition 过渡
  • inline 元素不支持 transform, 需要先变成 block

translate

X 是横轴,Y 是纵轴,Z 是屏幕向里的方向

常用语法

  • translateX(<length-percentage>)

    length 表示具体像素值,pecentage 表示元素长度的百分比,两者皆可使用

  • translateY(<length-percentage>)

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

    先 X 后 Y

  • translateZ(<length>) 且父元素要设置 perspective

    perspective:1000px表示视点位于视窗正中心 Z 轴方向上 1000px 远的地方

  • translate3d(x,y,z)

经验

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

scale

常用语法

  • scaleX(<number>)
  • scaleY(<number>)
  • scale(<number>,<number>?)

经验

较少使用,图片容易出现模糊

rotate

常用语法

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

    angle 单位是 deg | grad | rad | turn。默认是绕 Z 轴旋转

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

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

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

  • rotate3d([<number> |<number> |<number> |<angle>])

经验

一般用于 360deg 旋转制作 loading

skew

常用写法

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

多重效果

中间用空格隔开即可

transform: scale(0.5) translate(-100%, -100%);

取消所有

transform:none;

使用 transform: rotate 旋转后坐标轴也会旋转

实践

使用 transform 和 transition 实现跳动的心。

范例

作业

实践时发现 transform 中的 rotate 是以长方形右下角的定点为轴进行旋转

transition 过渡

作用

补充中间帧

语法

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

    transition: left 200ms linear
    

    过渡方式有 linear |ease | ease-in | ease-out | ease-in-out | cubic-bezier | step-start | step-end | steps

  • 可以用逗号分割两个不同属性

    transition: left 200ms, top 400ms
    
  • 可以用 all 代表所有属性

    transition: all 200ms
    

注意

并不是所有属性都有过渡

  • display: none => block 无法过渡

    display: none 即元素不可见,且不为其保留相应位置

  • visibility: hidden => visible 可以过渡

    visibility: hidden 即元素不可见但保留相应位置

  • background, opacity 可以过渡

    我感觉属性值可以连续变化的都可以过渡

  • 过渡必须要有起始点

    一般只有一次动画,hover 和 非 hover 时有两次

包括起始点与中间点的过渡

使用两次 transform

示例

  1. .a \xRightarrow{\text{transform}} .b
  2. 用 SetTimeoout 或者监听 transitioned 来确认到了中间点,此时移除类 .b,增加类 .c
  3. .b \xRightarrow{\text{transform}} .c

如果 .c 要延续 .b 的状态运动,一般 .c 中要包括 .b 的内容

使用 animation

示例

  1. 声明关键帧
  2. 添加动画

animation

@keyframes 语法

详见 MDN文档

from to 写法

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

百分数写法

@keyframes eg2{
    0% {top: 0; left:0;}
    30% {top: 50px;}
    60%, 70% {left: 50px;}
    100% {top: 100px; left:100%;}
}

animation 缩写语法

animation: 时长 duration| 过渡方式 timing-function| 延迟 delay| 次数 iteration-count| 方向 direction| 填充模式 fill-mode| 是否暂停 play-state| 动画名 name;

animation: duration | timing-function | delay | name

animation: duartion | name

  • 时长 1s or 1000ms

  • 过渡方式 linear |ease | ease-in | ease-out | ease-in-out | cubic-bezier | step-start | step-end | steps

  • 次数 3 or 2.6 or infinite

  • 方向 reverse | alternate | alternate-reverse

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

    需要动画停在最后一帧时使用 forwards. 演示

  • 是否暂停 paused | running

    可以通过添加按键,在 JS 根据按键是否按下来改变 animationPlayState 的状态

  • 动画名放哪里都可以

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Border调试法 在写css元素内容时必须加上这句,可以用来查看自己书写的CSS是否正确;如果呈现出的内容则说明...
    pang猴子阅读 251评论 0 0
  • Get Started • 动画的原理• 浏览器渲染原理• CSS动画优化• transform全解• trans...
    茜Akane阅读 384评论 0 1
  • 1. CSS 定位 (1) div分层 布局是屏幕上面的(x y轴),定位是垂直于屏幕的(z轴) 内联子元素 > ...
    HikariXyc阅读 608评论 0 0
  • 1 CSS的简介与历史 CSS (Cascading Style Sheets,层叠样式表)是用来控制网页在浏览器...
    苏wisdom阅读 447评论 0 0
  • 动画:24帧游戏:30帧现在大部分显示器的最低刷新频率为60Hz,即每秒60帧。 setInterval()制作动...
    Emist阅读 226评论 0 0