1、CSS中的动画
1.1 简介
目前由于该技术的规范还没有稳定,在使用前要先确保浏览器对其兼容性。 Animations是css3的一个模块,使用keyframes定义如何随着时间的移动改变CSS的属性值,可以通过指定它们的持续时间,重复次数,如何重复来控制关键帧的行为。Animations由两部分组成:css动画的配置,以及一系列的keyframes(用来描述动画的开始、过程、结束状态)。不需要了解任何Js技术即可完成动画的制作。
过渡(transition)与动画(animation)之间的区别
(1)不同点:过渡必须人为的触发才能执行;动画不需要认为的触发就能执行
(2)相同点:都是用来给元素添加动画的;都是系统新增的属性;都需要满足三要素才会有效果
1.2 属性介绍
animation-name
作用:指定要绑定到选择器的关键帧的名称,告诉系统需要执行哪个动画。
通过@keyframes
来设置动画序列,序列中每个关键帧描述动画元素在动画序列的特定时间内如何渲染。关键帧使用了一个百分比来表示在动画序列中出现的时间。0%表示动画的初始时间,也可以通过from关键字表示。100%表示动画的结束时间,也可以通过to关键字表示。
例如:
<div></div>
div{
animation-name: leftToRight; /*执行动画的名字*/
}
@keyframes 动画名字{
/* 动画初始位置 */
from{
margin-left: 0px;
}
/* 动画结束位置 */
to{
margin-left: 500px;
}
}
animation-duration
作用:动画持续时间
取值:time,指定动画播放完成花费的时间,单位s。默认值为 0,意味着没有动画效果。
animation-timing-function
作用:设置动画执行的速率
取值:
(1)linear,动画从头到尾的速度是相同的,即匀速。
(2)ease,默认,动画以低速开始,然后加快,在结束前变慢。(慢速-快-慢速)
(3)ease-in,动画以低速开始
(4)ease-out,动画以低速结束
(5)ease-in-out,动画以低速开始和结束
(6)cubic-bezier(n,n,n,n)在cubic-bezier函数中自己的值。取值为0~1的数值。
此外,还可以使用一个函数step(n,end),第一个参数是指定动画分割成多少个步骤,第二个参数是可选的,用于指定动画播放时的方向。
animation-delay
作用:设置页面加载完成后动画执行前的延迟间隔。
取值:time,定义动画开始前等待的时间,以秒或毫秒计。默认值为0。
animation-iteration-count
作用:定义动画的播放次数
取值:
(1)n,数字,表示播放次数
(2)infinite,无限次重复执行
animation-direction
作用:指定是否应该轮流反向播放动画
取值:
(1)normal,默认,执行完一次之后回到起点继续执行下一次
(2)alternate,往返执行,即到了末尾后,从末尾又执行到开始位置
(3)reverse,反向执行
animation-fill-mode
作用:规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到的元素的样式
取值:
(1)none,不做任何改变
(2)forwards,让元素结束状态保持动画最后一帧的样式
(3)backwards,让元素等待状态的时候显示动画第一帧的样式
(4)both,让元素等待状态显示动画第一帧的样式, 让元素结束状态保持动画最后一帧的样式
animation-play-state
作用:告诉系统当前动画是否需要暂停
取值:
(1)running,执行动画
(2)paused,暂停动画
速写连写格式:
animation:动画名称(animation-name) 动画时长(animation-duration) 动画运动速度(animation-timing-function) 延迟时间(animation-delay) 执行次数(animation-iteration-count) 往返动画(animation-direction);
补充:引入外部animate.css
(1)引入animate的cdn或本地animate.css文件
<link href="https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.min.css" rel="stylesheet">
(2)给指定元素加入class"animate__animated <动效名称>"
<div class="animate__animated animate__fadeInUpBig">你好 animate</div>
1.3 使用示例
1、示例一
代码实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>循环播放</title>
<style>
div{
width: 100px;
height: 100px;
background-color: red;
animation-name: leftToRight; /*执行动画的名字*/
animation-duration: 5s; /**/
animation-delay: 3s; /*页面加载完成后动画执行前的延迟时间*/
animation-timing-function: linear; /*执行速率*/
animation-iteration-count: infinite; /*动画播放次数*/
animation-direction: alternate; /*是否轮流反复播放*/
}
/*鼠标移动到图形上面时暂停*/
div:hover{
animation-play-state: paused;
}
/*
定义动画
格式: @keyframes 动画名字{}
*/
@keyframes leftToRight{
/* 动画初始位置 */
from{
margin-left: 0px;
}
/* 动画结束位置 */
to{
margin-left: 500px;
}
}
</style>
</head>
<body>
<div></div>
</body>
</html>
2、示例二
循环播放图片:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>相片循环播放</title>
<style>
/* 所有标签的外边距、内边距为0 */
*{
margin:0px;
padding: 0px;
list-style: none;
}
div{
width: 800px;
height: 300px;
background-color: black;
border: 2px solid red;
margin:100px auto;
/* 清除div的浮动,使照片在div内容内 */
overflow: hidden;
}
div ul{
width: 3000px;
height: 300px;
/* 设置动画效果:动画效果名 持续7s 匀速 无限重复 */
animation: play 7s linear infinite;
}
div ul li{
width: 400px;
height: 300px;
/* 给全体ul中的li设置浮动,使他们连在一起 */
float: left;
}
/* @keyframes 关键字指定动画效果 play是自定义效果的名字*/
@keyframes play{
/* 动画开始的位置:外边距为0处开始 */
from{
margin-left: 0;
}
/* 结束时候的位置:到达外边距-2200px处时结束 */
/* 为什么是-2200px,让图往左移动本质上是将图通过浮动连在一起,而图由放在ul标签中,
然后将整个ul设置动画效果左移,直到移动到div边框左边2200px处结束(在2200px位置时电脑上是看不到的图片的) */
to{
margin-left: -2200px;
}
}
</style>
</head>
<body>
<div>
<ul>
<li><img src="./images/ad7.jpeg"></li>
<li><img src="./images/ad8.jpg"></li>
<li><img src="./images/ad9.jpeg"></li>
<li><img src="./images/ad10.jpg"></li>
<li><img src="./images/ad11.jpg"></li>
<li><img src="./images/ad12.jpg"></li>
<li><img src="./images/ad7.jpeg"></li>
<li><img src="./images/ad8.jpg"></li>
</ul>
</div>
</body>
</html>
3、示例三
呼吸灯:别看久了。。。会瞎。。。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>呼吸灯</title>
<style>
.bg{
width:600px;
height: 600px;
background-color: black;
margin: 50px auto;
/* 设置父元素为相对定位,相对于页面来说的位置 */
position: relative;
/* 将盒模型设置为边框盒子:这种盒子的特点是整体的高度为height,宽度为width */
box-sizing: border-box;
}
.bg .smallCircle{
width: 200px;
height: 200px;
border: 20px solid white;
border-radius: 50%;
/* 设置子元素为绝对定位 */
position: absolute;
/* bottom和left都是子元素在父元素中的绝对位置 */
bottom: 200px;
left: 200px;
margin:0;
box-sizing: border-box;
animation: small 2s linear infinite;
}
.bg .middleCircle1{
width: 400px;
height: 400px;
border-radius: 50%;
border: 20px solid white;
position: absolute;
bottom: 100px;
left: 100px;
box-sizing: border-box;
animation: middle 4s linear infinite;
}
.bg .bigCircle{
width: 500px;
height: 500px;
border: 10px solid white;
border-radius: 50%;
position: absolute;
bottom:50px;
left:50px;
box-sizing: border-box;
}
/* border-color控制圈圈的边框颜色变化 */
/* transform属性中的scale控制大小变化:将圈圈从原大小的0.6逐渐放大到原来的1.3倍 */
@keyframes small{
0%{
border-color: white;
transform: scale(0.6);
}
25%{
border-color: rgb(214, 214, 51);
transform: scale(0.7);
}
50%{
border-color: rgb(177, 123, 24);
transform: scale(0.9);
}
75%{
border-color: rgb(193, 236, 128);
transform: scale(1.1);
}
100%{
border-color: rgb(55, 185, 55);
transform: scale(1.3);
}
}
@keyframes middle{
0%{
border-color: white;
transform: scale(0.6);
}
25%{
border-color: rgb(255, 0, 212);
transform: scale(0.7);
}
50%{
border-color: rgb(255, 0, 98);
transform: scale(0.9);
}
75%{
border-color: rgb(255, 47, 99);
transform: scale(1.1);
}
100%{
border-color: rgb(128, 0, 0);
transform: scale(1.3);
}
}
</style>
</head>
<body>
<div class="bg">
<div class="smallCircle"></div>
<div class="bigCircle"></div>
<div class="middleCircle1"></div>
</div>
</body>
</html>
- 示例四:“动画”
body{
background-color:#ccc;
}
div{
postion:absolute;
width:200px; /* 动画展示区域的宽度 */
height:100px; /* 动画展示区域的高度 */
backgound:url(media/bear.png) no-repeat;
animation:bear 1s steps(8) infinite, move 1s forwards; /* forwards 保留动画最后所处的位置*/
}
/* 熊从左边跑到右边的动画 */
@keyframes move{
0%{
left:0;
}
100%{
left:50%;
}
}
/* 熊动作动画 */
@keyframes bear{
0%{
background-position:0 0;
}
100%{
backgound-position:-1600px 0; /* 1600是整个图片的宽度,-号表示往左移动*/
transform:translateX(-50%) /* 用于让动画处于中间位置*/
}
}
2. 2D、3D转换模块
转换模块主要的作用就是通过几个方法将原来的元素位置做出改变,并且这个改变不会影响到其他元素在文档流中的布局。
2.1 2D转换模块
1、transform属性
transform 属性将元素应用从2D或3D转换。该属性允许我们对元素进行旋转、缩放、移动或者倾斜。
rotate()方法
作用:旋转
格式:rotate(45deg);
deg是单位,代表多少度
旋转轴向
概念:默认情况下所有元素都是围绕Z轴进行旋转
transform: rotateZ(45deg);
围绕x轴旋转
transform: rotateX(45deg);
围绕y轴旋转
transform: rotateY(45deg);
translate()方法
作用:平移;
transform:translate(100px,0px);
第一个参数代表水平方向
第二个参数代表竖直方向
补充:
translateX(x) 向X轴方向平移
translateY(x) 向Y轴方向平移
scale()方法
作用:缩放
transform:scale(1.5);
transform:sacle(0.5,0.5);
第一个参数:水平方向
第二各参数:竖直方向
如果取值是1, 代表不变;如果取值大于1, 代表需要放大如果取值小于1, 代表需要缩小;如果水平和垂直缩放都一样, 那么可以简写为一个参数
补充:
transform:scaleX(2)
transform:scaleY(2)
转换连写格式
transform: rotate(45deg) translate(100px, 0px) scale(1.5, 1.5);
注意:
(1)如果需要进行多个转换, 那么用空格隔开;
(2)注意属性的前后顺序,2D的转换模块会修改元素的坐标系, 所以旋转之后再平移就不是水平平移的
skew() 方法
skew() 方法使元素沿 X 和 Y 轴倾斜给定角度
div {
transform: skew(20deg, 10deg);
}
补充:
transform:skewX(20deg)
transform:skewY(20deg)
transition-origin 属性
transform-origin:xxxpx,xxxpx;
形变中心点
第一个参数:水平方向
第二个参数:竖直方向
取值有三种形式
具体像素
transform-origin: 200px 0px;
百分比
transform-origin: 50% 50%;
transform-origin: 0% 0%;
特殊关键字
transform-origin: center center;
注意:默认情况下所有的元素都是以自己的中心点作为参考来旋转的, 我们可以通过形变中心点属性来修改它的参考点
matrix() 方法
matrix() 方法把所有 2D 变换方法组合为一个。
matrix() 方法可接受六个参数,其中包括数学函数,这些参数使您可以旋转、缩放、移动(平移)和倾斜元素。
参数如下:
matrix(scaleX(),skewY(),skewX(),scaleY(),translateX(),translateY())
例如:
div {
transform: matrix(1, -0.3, 0, 1, 0, 0);
}
2、使用示例
<style>
.container {
margin: auto;
width: 300px;
height: 100px;
}
div[class^="demo"] {
width: 100px;
height: 100px;
background-color: rgb(221, 108, 55);
margin: 10px;
}
.demo1 {
transition: all 0.8s ease;
}
.demo1:hover {
transform: translate(0, -30px);
}
.demo2 {
transition: all 2s ease;
}
.demo2:hover {
transform: rotate(90deg);
}
.demo3 {
transition: all 1.5s ease-in;
}
.demo3:hover {
transform: scale(2);
}
.demo4 {
transition: all 1.5s ease-out;
}
.demo4:hover {
transform: translate(200px, 200px) rotate(90deg);
}
.demo5 {
transition: all 1.5s ease-in-out;
}
.demo5:hover {
transform: rotate(90deg) translateX(200px);
}
</style>
</head>
<body>
<div class="container">
<div class="demo1">2d平移</div>
<div class="demo2">2d旋转</div>
<div class="demo3">2d放大</div>
<div class="demo4">先平移后旋转</div>
<div class="demo5">边旋转边平移</div>
</div>
</body>
2.2 3D转换模块
2.2.1 属性
属性 | 描述 |
---|---|
transform | 转换模式为2D或者3D,属性值为转换方法 |
transform-origin | 改变轴原点位置,属性值(x,y,z),分别定义视图在各个轴上的位置,其中x可以为left、center、right、length、% ,y可以为top、center、bottom、length、% ,z可以为length |
transform-style | 规定被嵌套的元素是否按照3D显示,取值有:flat、preserve-3d; ,flat表示子元素将不保留其 3D 位置;preserve-3d表示子元素保留其3D位置。 |
perspective | 设置透视,取值:number、1none; ,其中number是元素距离视图的距离,以像素计,none表示不透视,通常用于父元素上。 |
perspective-origin | 该属性用于定义 3D 元素所基于的 X 轴和 Y 轴。 |
backface-visibility | 定义元素在不面对屏幕时是否可见,简单来说就是当元素背面翻转过来时元素不可见,取值有:visible、hidden |
2.2.2 方法
perspective(n),在2D平面产生近大远小视觉立体,透视可以理解成3D物体投影在2D平面内,单位是像素。透视要写在被观察元素的父盒子上面。
2.2.3 使用示例
- 示例一
<style>
.container {
width: 200px;
perspective: 2000px;
margin: 50px auto;
}
.box {
width: 200px;
height: 200px;
margin-top: 20px;
display: inline-block;
transition: all 2s ease;
background-image: linear-gradient(
to bottom right,
red,
yellow
) !important;
}
.rotateX:hover {
transform: rotateX(180deg);
}
.rotateY:hover {
transform: rotateY(180deg);
}
.rotateZ:hover {
transform: rotateZ(180deg);
}
.translateX:hover {
transform: translateX(100px);
}
.translateY:hover {
transform: translateY(100px);
}
.translateZ:hover {
transform: translateZ(100px);
}
.scaleX:hover {
transform: scaleX(2);
}
.scaleY:hover {
transform: scaleY(2);
}
.scaleZ:hover {
transform: scaleZ(2);
}
</style>
</head>
<body>
<div class="container">
<!-- 实现卡片沿轴翻转效果 -->
<!-- 沿x轴 -->
<div class="box rotateX"></div>
<!-- 沿y轴 -->
<div class="box rotateY"></div>
<!-- 沿z轴 -->
<div class="box rotateZ"></div>
<!-- 卡片沿轴平移 -->
<!-- 沿x轴 -->
<div class="box translateX"></div>
<!-- 沿x轴 -->
<div class="box translateY"></div>
<!-- 沿z轴 -->
<div class="box translateZ"></div>
<!-- 沿轴放大 -->
<!-- 沿x轴 -->
<div class="box scaleX"></div>
<!-- 沿x轴 -->
<div class="box scaleY"></div>
<!-- 沿x轴 -->
<div class="box scaleZ"></div>
</div>
</body>
-
ratateX()
-
rotateY()
-
rotateZ()
-
translateX()
-
translateY()
-
translateZ()
-
scaleX()
-
scaleY()
-
scaleZ()
在使用rotate()方法的时候,其参数值可以传正数,也可以传负数,用来控制旋转方向,有这样一种判断方法,左手定则,左手拇指伸直,指向轴的方向,其他手指弯曲,指向的是旋转的方向为正值,反之为负值。
- 示例二:两面翻转盒子
如图
<style>
.container {
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
transition: all 0.8s ease;
/* 让没有出现在人眼前的元素依旧保持3D效果 */
transform-style: preserve-3d;
/* 给父元素添加透视 */
perspective: 800px;
}
/* 将外边的容器整体翻转 */
.container:hover {
transform: rotateY(180deg);
}
.front,
.reverse {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
border-radius: 50%;
line-height: 200px;
text-align: center;
font-size: 30px;
color: #fff;
/* 将元素背面隐藏 */
backface-visibility: hidden;
box-shadow: 0 4px 20px #4b4747;
}
.front {
background-color: rgb(239, 53, 84);
/* 让当前盒子先显示 */
z-index: 1;
}
.reverse {
background-color: rgb(11, 191, 227);
transform: translateZ(1px);
/* 显示翻转过来的内容 */
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div class="container">
<div class="front">前面</div>
<div class="reverse">后面</div>
</div>
</body>
- 示例二:翻转的导航栏
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
margin: 100px;
}
ul li {
width: 120px;
height: 40px;
/* 透视 */
perspective: 800px;
}
.box {
position: relative;
width: 100%;
height: 100%;
transition: all 0.8s;
/* 让子元素转换时维持3D状态 */
transform-style: preserve-3d;
}
.front,
.bottom {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.front {
background-color: rgb(84, 242, 226);
z-index: 1;
transform:translateZ(20px)
}
.bottom {
background-color: rgb(36, 223, 71);
transform: translateY(20px) rotateX(-90deg);
}
.box:hover {
transform: rotateX(90deg);
}
</style>
</head>
<body>
<ul>
<li>
<div class="box">
<div class="front">前面</div>
<div class="bottom">下面</div>
</div>
</li>
</ul>
</body>
- 旋转木马
<style>
body {
perspective: 1000px;
}
.container {
position: relative;
width: 300px;
height: 200px;
margin: 100px auto;
transform-style: preserve-3d;
/* 添加动画效果 */
animation: rotate 10s linear infinite;
}
/* 动画帧 */
@keyframes rotate {
0% {
transform: rotateY(0);
}
100% {
transform: rotateY(360deg);
}
}
/* 鼠标放上去动画停止 */
.container:hover {
animation-play-state: paused;
}
.container div {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
/* TODO:待添加图片 */
background: url(/image/pikaqiu.jpg) no-repeat center;
}
.container div:nth-child(1) {
transform: translateZ(300px);
}
.container div:nth-child(2) {
transform: rotateY(60deg) translateZ(300px);
}
.container div:nth-child(3) {
transform: rotateY(120deg) translateZ(300px);
}
.container div:nth-child(4) {
transform: rotateY(180deg) translateZ(300px);
}
.container div:nth-child(5) {
transform: rotateY(240deg) translateZ(300px);
}
.container div:nth-child(6) {
transform: rotateY(300deg) translateZ(300px);
}
</style>
</head>
<body>
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</body>