13·灵魂前端工程师养成-CSS动画

2022-09-26 16:57:20 浏览数 (1)

  • CSS动画原理
  • 浏览器渲染原理
  • transform完整介绍
  • 跳动的心制作
  • transition 过渡属性
  • 使用animation做动画
  • 使用animation制作跳动的红心

-曾老湿, 江湖人称曾老大。


-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。


CSS动画原理


定义

动画实际上是由许多静止的画面(帧)组成的。

以一定的速度 (如每秒30张)连续播放时,肉眼因视觉残象产生错觉,而误以为是活动的画面。

帧:每个静止的画面都叫做帧 播放速度:每秒24帧(影视),每秒最低30帧(游戏),现在的游戏希望每秒60帧,或者120帧。


做动画的最简单例子:方法一

将div从左往右移动

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

html

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="demo"></div>
</body>
</html>

CSS

代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  position: relative;
  left: 0;
}

JavaScript

代码语言:javascript复制
var n = 1

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

可以看见,方框是在动的


做动画的最简单例子:方法二

html

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
    <div id="demo"></div>
</body>
</html>

CSS

代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  transition: all 1s linear;
}

#demo.end{
  transform: translateX(200px);
}

JavaScript

代码语言:javascript复制
setTimeout(()=>{
  demo.classList.add('end')
},3000)

本来没有end,运行3秒后,会出现一个end


CSS的性能

方法一的性能如下:

1.打开开发者工具

2.在任何一个 type页面,按ESC都会出来一个控制台,点击前面竖着的三个点,有些人可能是两个点,不要问我为什么点数不一样,这不是重点....

3.选择Rendering

4.勾选Paint flashing

如果捕捉到动态的物体,会用绿色的框包裹起来。绿色表示,画一个图,擦掉重新画。这个框,从头绿到尾

方法二的性能:

不难发现,在 运行的过程中,框一开始是绿的,中间是白色的,结束还是绿色的,也就是说,擦掉重新画的过程只发生了3次,所以,这个方法的性能,会比第一个方法的性能高很多。

浏览器渲染原理

Google团队写的文章

渲染树构建、布局及绘制

渲染性能

使用transform来实现动画

浏览器渲染过程

步骤:

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


使用JS更新样式

1.div.style.background='red' 2.div.style.display='none' 3.div.classList.add('red') 4.div.remove()

1.JS/CSS>样式>布局>绘制>合成 (全走)

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

代码语言:javascript复制
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>

<body>
    <div id="demo"></div>
    <div class=other>1</div>
    <div class=other>2</div>
</body>

</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  transition: all 1s linear;
}

#demo.end{
  transform: translateX(300px);
}
.other{
  width: 100px;
  height: 100px;
  border: 1px solid red;
}
代码语言:javascript复制
setTimeout(()=>{
  demo.remove()
},3000)

2.JS/CSS>样式>绘制>合成 (跳过Layout)

改变背景颜色 ,直接repaint composite

代码语言:javascript复制
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>

<body>
    <div id="demo"></div>
    <div class=other>1</div>
    <div class=other>2</div>
</body>

</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  transition: all 1s linear;
}

#demo.end{
  transform: translateX(300px);
}
.other{
  width: 100px;
  height: 100px;
  border: 1px solid red;
}
代码语言:javascript复制
setTimeout(()=>{
  demo.style.background = 'red'
},3000)

3.JS/CSS>样式>合成 (跳过layout和paint)

改变transform 只需composite

代码语言:javascript复制
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>

<body>
    <div id="demo"></div>
    <div class=other>1</div>
    <div class=other>2</div>
</body>

</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  transition: all 1s linear;
}

#demo.end{
  transform: translateX(300px);
}
.other{
  width: 100px;
  height: 100px;
  border: 1px solid red;
}
代码语言:javascript复制
setTimeout(()=>{
  demo.style.transform = 'translateX(100px)'
},3000)

那我怎么知道CSS什么属性触发什么样的渲染效果?

CSS各属性触发什么

注意:前端高手,不用left做动画,性能低

transform完整介绍

CSS动画优化:

1.CSS中,left变成transform 2.JS优化:使用requestAnimationFrame代替setTimeoutsetInterval 3.CSS优化:使用will-changetranslate

具体答案:Google文章


1.语法

代码语言:javascript复制
/* Keyword values */
transform: none;

/* Function values */
transform: matrix(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
transform: translate(12px, 50%);
transform: translateX(2em);
transform: translateY(3in);
transform: scale(2, 0.5);
transform: scaleX(2);
transform: scaleY(0.5);
transform: rotate(0.5turn);
transform: skew(30deg, 20deg);
transform: skewX(30deg);
transform: skewY(1.07rad);
transform: matrix3d(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0);
transform: translate3d(12px, 50%, 3em);
transform: translateZ(2px);
transform: scale3d(2.5, 1.2, 0.3);
transform: scaleZ(0.3);
transform: rotate3d(1, 2.0, 3.0, 10deg);
transform: rotateX(10deg);
transform: rotateY(10deg);
transform: rotateZ(10deg);
transform: perspective(17px);

/* Multiple function values */
transform: translateX(10px) rotate(10deg) translateY(5px);

/* Global values */
transform: inherit;
transform: initial;
transform: unset;

transform属性可以指定为关键字值none 或一个或多个值。


2.值

<transform-function> 要应用的一个或多个CSS变换函数。 变换函数按从左到右的顺序相乘,这意味着复合变换按从右到左的顺序有效地应用。

none 不应用任何变换。


3.语法格式

代码语言:javascript复制
none | <transform-list>

where 
<transform-list> = <transform-function> 

where 
<transform-function> = <matrix()> | <translate()> | <translateX()> | <translateY()> | <scale()> | <scaleX()> | <scaleY()> | <rotate()> | <skew()> | <skewX()> | <skewY()> | <matrix3d()> | <translate3d()> | <translateZ()> | <scale3d()> | <scaleZ()> | <rotate3d()> | <rotateX()> | <rotateY()> | <rotateZ()> | <perspective()>

where 
<matrix()> = matrix( <number>#{6} )
<translate()> = translate( <length-percentage> , <length-percentage>? )
<translateX()> = translateX( <length-percentage> )
<translateY()> = translateY( <length-percentage> )
<scale()> = scale( <number> , <number>? )
<scaleX()> = scaleX( <number> )
<scaleY()> = scaleY( <number> )
<rotate()> = rotate( [ <angle> | <zero> ] )
<skew()> = skew( [ <angle> | <zero> ] , [ <angle> | <zero> ]? )
<skewX()> = skewX( [ <angle> | <zero> ] )
<skewY()> = skewY( [ <angle> | <zero> ] )
<matrix3d()> = matrix3d( <number>#{16} )
<translate3d()> = translate3d( <length-percentage> , <length-percentage> , <length> )
<translateZ()> = translateZ( <length> )
<scale3d()> = scale3d( <number> , <number> , <number> )
<scaleZ()> = scaleZ( <number> )
<rotate3d()> = rotate3d( <number> , <number> , <number> , [ <angle> | <zero> ] )
<rotateX()> = rotateX( [ <angle> | <zero> ] )
<rotateY()> = rotateY( [ <angle> | <zero> ] )
<rotateZ()> = rotateZ( [ <angle> | <zero> ] )
<perspective()> = perspective( <length> )

where 
<length-percentage> = <length> | <percentage>

重点记住

上面写了好多呀,它们都是干嘛的呀?.... 忘记它们,记住下面的。

transform四个常用功能:

1.位移:translate

常用写法

代码语言:javascript复制
translateX( <length-percentage> )
translateY( <length-percentage> )
translate( <length-percentage>,<length-percentage>? )
translateZ( <length> )且父容器perspective
translate3d(x,y,z)

1)translateX 横向移动,代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
}

/*hover是鼠标移上去的意思*/
#demo:hover{
  transform: translateX(50px);
}

2)translateY 纵向移动,代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
}

/*hover是鼠标移上去的意思*/
#demo:hover{
  transform: translateY(50px);
}

3)translateZ 垂直屏幕移动,代码如下:

因为在CSS中是二维的,所以我们没法看到这个图片发生的变化,所以我们需要把他变成三维的。

如果想变成三维的,必须要告诉程序视点在哪里,这就是为什么刚才代码中,在demo的外层加个wrapper

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
}

/*hover是鼠标移上去的意思*/
#demo:hover{
  transform: translateZ(0px);
}

.wrapper{
  perspective: 1000px;
  border: 1px solid black;
}

4)translate 水平纵向移动,代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
}

/*hover是鼠标移上去的意思*/
#demo:hover{
  transform: translate(50px,50px);
}

.wrapper{
  perspective: 1000px;
  border: 1px solid black;
}

5)translate3d 水平纵向垂直屏幕移动

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
}

/*hover是鼠标移上去的意思*/
#demo:hover{
  transform: translate3d(50px,50px,200px);
}

.wrapper{
  perspective: 1000px;
  border: 1px solid black;
}


注意:我们一般用 translate(-50%,-50%)可做绝对定位元素中的居中。

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  position: absolute;
  left: 50%;
  top:50%;
  transform: translate(-50%,-50%);
}


.wrapper{
  border: 1px solid black;
  position: relative;
  height: 500px;
}


2.缩放:scale

1)scale 变大,代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
  /*1秒钟之内变大*/
  transition: all 1s;
}


#demo:hover{
  transform: scale(1.5)
}

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
  /*1秒钟之内变大*/
  transition: all 1s;
}


#demo:hover{
  transform: scale(1.5,0.5)
}

2)scaleX 变胖,代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
  /*1秒钟之内变大*/
  transition: all 1s;
}


#demo:hover{
  transform: scaleX(1.5)
}

3)scale 变高,代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
  /*1秒钟之内变大*/
  transition: all 1s;
}


#demo:hover{
  transform: scaleY(1.5)
}


注意:scale一般用的比较少,因为可能会变模糊


3.旋转:rotate

语法:

代码语言:javascript复制
rotate([<angle>|<zero>])
rotateZ([<angle>|<zero>])
rotateX([<angle>|<zero>])
rotateY([<angle>|<zero>])

1)rotate 旋转围绕垂直屏幕的轴,代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
  /*1秒钟之内变大*/
  transition: all 1s;
}


#demo:hover{
  transform: rotate(45deg)
}

同样可以空中转体360,或者三周半...360 , 1080即可。

2)rotateX 旋转围绕横轴,代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
  /*1秒钟之内变大*/
  transition: all 1s;
}


#demo:hover{
  transform: rotateX(45deg)
}

 如果空间感好的话,你会发现,它并不是变矮了,而是在向前旋转了45度,有点像迈克尔杰克逊,那个舞蹈。

3)rotateY 旋转围绕纵轴,代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
  /*1秒钟之内变大*/
  transition: all 1s;
}


#demo:hover{
  transform: rotateY(45deg)
}

一般用于 loading... 加载页面 中间的圆圈,旋转

4.倾斜:skew

语法:

代码语言:javascript复制
skewX( [<angle>|<zero>] )
skewY( [<angle>|<zero>] )
skew( [<angle>|<zero>,<angle>|<zero>]?)

用得少

1)skewX 在X轴方向倾斜,代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
  /*1秒钟之内变大*/
  transition: all 1s;
}


#demo:hover{
  transform: skewX(15deg)
}

2)skewX 在Y轴方向倾斜,代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
  /*1秒钟之内变大*/
  transition: all 1s;
}


#demo:hover{
  transform: skewY(15deg)
}

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


组合使用

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 200px;
  border: 1px solid red;
  margin: 50px;
  /*1秒钟之内变大*/
  transition: all 1s;
}


#demo:hover{
  transform: scale(1.5) rotate(45deg) skewY(15deg);
}

跳动的心制作

思路,可以看成是两个圆形,加上一个45度的正方形。

改回方形,旋转45度

去除 border 加 颜色

代码语言:javascript复制
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>

<body>
  <div id="heart">
    <div class="left"></div>
    <div class="right"></div>
    <div class="bottom"></div>
  </div>
</body>

</html>
代码语言:javascript复制
*{margin:0;padding:0;box-sizing: border-box;}

#heart{
  margin: 100px;
  display: inline-block;
  /*相对定位*/
  position: relative;
  transition: all .5s;
}

#heart>.bottom{
  width: 50px;
  height: 50px;
  /*旋转正方形 45度*/
  transform: rotate(45deg);
  background: red;
}

#heart>.left{
  width: 50px;
  height: 50px;
  border-radius: 50% 0 0 50%;
  /*绝对定位*/
  position: absolute;
  bottom: 100%;
  right: 100%;
  transform: rotate(45deg) translateX(41px);
  background: red;
}

#heart>.right{
  width: 50px;
  height: 50px;
  border-radius: 50% 50% 0 0;
  /*绝对定位*/
  position: absolute;
  bottom: 100%;
  left: 100%;
  transform: rotate(45deg);
  transform: rotate(45deg) translateY(41px);
  background: red;
}

#heart:hover{
  transform: scale(1.5);
}

transition 过渡属性

作用:添加中间帧,可以看到图像在变形的时候,会像动画一样。


语法

代码语言:javascript复制
transition:属性名 时长 过渡方式 延迟

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

示例:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="demo"></div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  transition: width 1s;
}

/*demo拥有end的时候*/
#demo.end{
  width: 200px;
  
}

#demo:hover{
  width: 200px;
}


注意:并不是所有属性都能过渡 display: none => block 没法过渡 一般改成visibility: hidden => visible background颜色可以过渡吗? opacity透明度可以过渡嘛?

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="demo"></div>
  <button id="x">start</button>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  transition: all 1s;
  opacity: 1;
}

/*demo拥有end的时候*/
#demo.end{
  width: 200px;
  height: 200px;
  opacity: 0;
}
代码语言:javascript复制
x.onclick = ()=>{
  demo.classList.add('end')
  setTimeout(()=>{
    demo.remove()
  },1000)
}

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="demo"></div>
  <button id="x">start</button>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  transition: all 1s;
  background: black;
}

/*demo拥有end的时候*/
#demo.end{
  width: 200px;
  height: 200px;
  background: white;
}
代码语言:javascript复制
x.onclick = ()=>{
  demo.classList.add('end')
  setTimeout(()=>{
    demo.remove()
  },1000)
}

使用两次transform,实现动画效果

代码语言:javascript复制
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>

<body>
  <div class="wrapper">
    <div id="demo"></div>
    <button id="x">start</button>
  </div>
</body>

</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  margin: 50px;
  transition: all 1s linear;
  background: black;
}

#demo.b{
  transform: translateX(200px);
  background: blue;
}

#demo.c{
  transform: translateX(200px) translateY(100px);
  background: yellow;
}
代码语言:javascript复制
x.onclick = ()=>{
  demo.classList.add('b')
  setTimeout(()=>{
    demo.classList.remove('b')
    demo.classList.add('c')
  },1000)
}

使用animation做动画

animation是真正的动画属性。


声明关键帧

使用animation,声明一下关键正,然后添加animation属性,到一个元素上。

完整语法一:

代码语言:javascript复制
@keyframes xxx{
  from {
    transform: translateX(0%);
  }
  
  to {
    transform: translateY(100%);
  }
}

完整语法二:

代码语言:javascript复制
@keyframes xxx{
  0% { top: 0; left: 0; }
  30% { top: 50px; }
  68%,72% { left: 50px; }
  100% { top: 100px; left: 100px; }
}

缩写语法:

代码语言:javascript复制
animation: 时长|过渡方式|延迟|次数|方向|填充模式|是否暂停|动画名;

时长: 1s 或 1000ms
过渡方式:跟transition 取值一样,例如:linear
次数:3 或者 2.4 或者 infinite
方向:reverse|alternate|alternate-reverse
填充模式:none|forwards|backwards|both
是否暂停:paused|running

例如:

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
    <button id="button">开始动画</button>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  margin: 50px;
}

#demo.start{
  animation: 1.5s xxx linear 1s infinite alternate;
}

@keyframes xxx{
  0% {transform: none; background: white;}
  66.66% {transform: translateX(200px); background: blue;}
  100% {transform: translateX(200px) translateY(200px); background: green;}
}
代码语言:javascript复制
button.onclick = ()=>{
  demo.classList.add('start')
}

加上暂停和继续

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div id="demo"></div>
    <button id="kaishi">开始动画</button>
    <button id="zanting">暂停动画</button>
    <button id="jixu">继续动画</button>
    <button id="tingzhi">停止动画</button>
  </div>
</body>
</html>
代码语言:javascript复制
#demo{
  width: 100px;
  height: 100px;
  border: 1px solid red;
  margin: 100px;
}

#demo.start{
  animation: 1.5s linear 1s infinite alternate xxx;
}

@keyframes xxx{
  0% {transform: none; background: white;}
  66.66% {transform: translateX(200px); background: blue;}
  100% {transform: translateX(200px) translateY(200px); background: green;}
}
代码语言:javascript复制
kaishi.onclick = ()=>{
  demo.classList.add('start')
}

zanting.onclick = ()=>{
  demo.style.animationPlayState = 'paused'
}

jixu.onclick = ()=>{
  demo.style.animationPlayState = 'running'
}

tingzhi.onclick = ()=>{
  demo.classList.remove('start')
}

使用animation制作跳动的红心

代码语言:javascript复制
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>

<body>
  <div id="heart">
    <div class="left"></div>
    <div class="right"></div>
    <div class="bottom"></div>
  </div>
</body>

</html>
代码语言:javascript复制
*{margin:0;padding:0;box-sizing: border-box;}

#heart{
  margin: 100px;
  display: inline-block;
  /*相对定位*/
  position: relative;
  animation: heart 1s infinite alternate;
  
}

@keyframes heart{
  0% {
    transform: scale(1.0);
  }
  
  100% {
    transform: scale(1.5);
  }
}

#heart>.bottom{
  width: 50px;
  height: 50px;
  /*旋转正方形 45度*/
  transform: rotate(45deg);
  background: red;
}

#heart>.left{
  width: 50px;
  height: 50px;
  border-radius: 50% 0 0 50%;
  /*绝对定位*/
  position: absolute;
  bottom: 100%;
  right: 100%;
  transform: rotate(45deg) translateX(41px);
  background: red;
}

#heart>.right{
  width: 50px;
  height: 50px;
  border-radius: 50% 50% 0 0;
  /*绝对定位*/
  position: absolute;
  bottom: 100%;
  left: 100%;
  transform: rotate(45deg);
  transform: rotate(45deg) translateY(41px);
  background: red;
}

#heart:hover{
  transform: scale(1.5);
}

0 人点赞