CSS 动画

140 阅读4分钟

CSS动画

通过setInterval制作一个动画

var n = 1;
const timer =  setInterval(()=>{
    demo.style.left = (n++) + 'px';
    // console.log(n++);
    if(n==500){
        clearTimeout(timer);
    }
},1000/60)

注意:这样会有很大的性能问题,因为每动一次都会重新渲染

浏览器渲染原理

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

image-20220522211350988.png

三种渲染方式

image-20220522211710692.png

第一种,全走

div.remove()会触发当前消失,其他元素relayout,因为其他元素的布局位置改了

第二种,跳过layout

改变背景颜色,直接repaint + composite,布局位置和大小都没变,只改变了一些属性

第三种,跳过layout和paint

改变transform,只需composite

CSS 动画优化

渲染优化

使用渲染少的属性

js优化

使用requestAnimationFrame代替setTimeout或setInterval

CSS优化

使用will-change或translate

2D变形(CSS3)transform

transform可以实现元素的位移、旋转、倾斜、缩放,甚至支持矩阵方式,配合过度和动画可以实现Flash才能实现的效果。

移动 translate

transform:translate(50px,50px)  /* translate进行平移 */
transform:translateX(50px)  /* 仅向水平方向进行平移 */
transform:translateY(50px)  /* 仅向垂直方向进行平移 */
transform:translate(50%)  /* 水平移动盒子自身宽度的50% */

使用translate方法来将文字或者图像在水平方向和垂直方向移动,x、y可为负值

缩放 scale

transform:scale(1.2,1.5);  /* 水平缩放,垂直缩放 */

旋转 rotate

transform:rotate(720deg)/* 旋转 */

使用rotate方法可以进行元素的旋转

调整旋转基准点

transform-origin: /* 可以改变旋转的中心点,默认是50% 50%也就是图形的中心点第一个参数是x轴,第二个参数是y轴 */ 
transform-origin:50% 50%;
transform-origin:buttom left;
transform-origin:20px 30px;

倾斜 skew

transform:skew(20deg)/* 倾斜20° 只有一个参数表示x轴倾斜20° */
transform:skew(20deg,30deg)/* 两个参数时,第一个参数表示x轴倾斜20°(上下两边不动,左右两边进行倾斜),第二个参数表示y轴倾斜30°(左右两边不动上下两边进行倾斜)*/

3D变形(CSS3)transform

CSS坐标系

image-20220302222102100.png

transform:rotateX(720deg)/* 绕X轴转 */
transform:rotateY(720deg)/* 绕Y轴转 */
transform:rotateZ(720deg)/* 绕Y轴转 */

透视 perspective

通过透视可以将一个2D平面在转换的过程中,呈现出3D的视觉效果

perspective一般作为一个属性设置给父元素,作用于所有3D转换的子元素

perspective: 500px;

注意:视距越大效果越不明显,视距越小效果越明显

3D移动 translateZ(z)效果

需要配合perspective来体现

backface-visibility

backface-visibility属性定义当元素不面向屏幕时是否可见。

过渡(transition)

帧动画:通过一帧一帧的画面按照固定顺序和速度进行播放

CCS3中可以使用transition进行实现过度效果,并且当前元素只要有属性发生变化,即存在两种状态,就可以实现平滑的过度效果,为了方便演示采用hover切换两种状态。不局限于只有hover来实现过渡。

语法格式:

transition:要过度的属性 花费时间 运动曲线 合适开始;
如果有多组属性变化,用逗号隔开。
​
<!--过渡属性transition-->
<!--
    transition-property:过渡属性(默认值为all)(例如height、width)
    transition-duration:过渡持续时间(默认值为0s)
    transiton-timing-function:过渡函数(默认值为ease函数)
        ease:先慢后快再慢
        ease-out:先慢后快
        easr-in-out:开始和结束都慢中间快
        step-start:开始时进行变化,表现为没有动画
        step-end:结束时进行变化
    transition-delay:过渡延迟时间(默认值为0s)(比如鼠标要停留0.2s才会发生变化)
-->
<!--
    简写写法: 
    transition:all 2s ease .2s;
-->

注意:transition内容放在原标签里,并非放在hover中

运动曲线示意图

image-20220302161545823.png

不能使用过度的属性

dispaly:none => block 没有办法过渡,一般用visibility:hidden=> visible代替

动画(CSS3)animation

动画 animation

animation复合属性
    animation-name 要使用的关键帧的名字
    animation-duration 动画运行所需要的时间
    animation-timing-function
        linear 匀速播放
        ease 先慢后快再慢
        ease-in-out 先慢后快再慢
        ease-in 开始慢然后逐渐加快
        ease-out 开始快然后逐渐变慢
    animation-delay 延时多少秒之后执行 (做delay延迟效果的时候尽量使用负延时)
    animation-iteration-count 动画循环的次数 (infinite:无限循环)
    animation-direction 
        normal 正常运行
        reverse 反方向运行
        alternate 正着运行一次,反着运行一次
    animation-play-state
        running 运行的
        paused 暂停的
animation连贯写法
    animation:动画名称 动画时间 运动曲线 何时开始 播放次数 是否反方向;
    animation: mymove 5s 3;
    使用mymove的关键帧,运行时间是5秒,重复3

关键帧 @keyframes

<!--关键帧-->
<!--从开始到结束-->
from{top: 0;left: 20%;}
to{top:0;left: 80%;}
<!--分阶段进行定义-->
0% {top: 0;left: 20%; background-color: red;}
25% {top:0;left: 80%; background-color: yellow;} 
50%,60% {top:80%;left:80%; background-color: green;}
75% {top:80%;left:20%; background-color: blue;}
100% {top:0%;left: 20%; background-color: red;}

让动画停在最后一帧

animation: bubble 1.0s forwards;
/* forwards使得动画停在最后一帧 */