🎉目标:通过两篇文章的学习 (理论+实例)+实战 熟悉并掌握CSS3动画
- 通过理论+实例了解并熟悉动画的实现 ✅
- 基于vue实战来完成并掌握动画的实现 ✅
📬part1 理论+实例
本期文章字数1w+阅读需要20分钟左右,建议收藏后慢慢学习。
🌅1. 过渡
过渡(transition)可以为一个元素在不同状态之间切换的时候定义不同的过渡效果。比如在不同的伪元素之间切换,像是 :hover,:active 或者通过 JavaScript 实现的状态变化。 同时提供了一种在更改 CSS 属性时控制动画速度的方法。
官方文档: 1. transition - CSS: 叠层样式表 | MDN 2. 使用 CSS transitions
1.1. 属性值
1.1.1. transition-property
transition-property 用于指定哪个或哪些 CSS 属性用于过渡。只有指定的属性才会在过渡中发生动画,其他属性仍如通常那样瞬间变化。
/* 语法 */
transition-property: 过渡属性的名称
/* 取值 */
none: 没有过渡动画
all: 所有可被动画的属性都表现出过渡动画
属性名: 需要过渡属性的名称
/* 示例 */
transition-property: none;
transition-property: all;
transition-property: width, height, opacity, left, top;
/* 注意 */
多个过渡属性中间以 , 隔开(如示例3)
1.1.2. transition-duration
transition-duration 用于设置属性以秒或毫秒为单位,指定过渡动画所需的时间。默认值为 0s,表示不出现过渡动画。
/* 语法 */
transition-duration: 动画所需的时间
/* 取值 */
<time>类型
/* 示例 */
transition-duration: 3s;
transition-duration: 1s 2s 3s;
/* 注意 */
1. 有多个过渡时间以 , 隔开(如示例2),
并且每个时长会被应用到由 transition-property 指定的对应属性上
2. 时间默认为0,表示不会呈现过渡动画,属性会瞬间完成转变, 不能为负值
1.1.3. transition-delay
transition-delay 用于规定在过渡效果开始作用之前需要等待的时间,即延迟多久执行动画。
/* 语法 */
transition-delay: 过渡等待的时间
/* 取值 */
<time>类型
/* 示例 */
transition-delay: 3s;
transition-delay: 1s 2s 3s;
/* 注意 */
1. 有多个等待时间以 , 隔开(如示例2),
并且每个时长会被应用到由 transition-property 指定的对应属性上
2. 时间默认为0,取值为正时会延迟一段时间来响应过渡效果;取值为负时会导致过渡立即开始。
1.1.4. transition-timing-function
transition-timing-function 用于规定在过渡效果执行时采取的时序函数。
/* 语法 */
transition-timing-function: 时序函数
/* 取值 */
<timing-function>类型
linear: 匀速运动
ease: 慢速开始,先加速后减速 [ 默认值 ]
ease-in: 加速运动
ease-out: 减速运动
ease-in-out: 先加速后减速
cubic-bezier(): 贝塞尔曲线
steps(): 分步执行过渡效果
- end,在时间结束时执行过渡(默认值)
- start,在时间开始时执行过渡
/* 示例 */
transition-timing-function: ease-out;
transition-timing-function: steps(8, end);
1.2. 实例
这部分只是作为不同属性设置而执行不同动画的效果展示,以便更易理解上述属性。实例实现较为简单,所以没有放上代码,需要实践操作一下😽 动手试一试→
1.2.1. 实例1 简单的放大过渡
黑色背景为box,图片为box的子元素box1,鼠标悬浮在box上,box1放大。下面的属性写到box1中
transition-property:width , height;
transition-duration:1s;
当未设置transition-duration属性值时,动画将立即执行而没有过渡效果:
1.2.2. 实例2 简单的多属性过渡
这里设置了大小、颜色、阴影等属性的过渡,因为属性较多所以设置 transition-property:all
同时设置了1.5s的延时
1.2.3. 实例3 简单的不同过渡时序的动画比较
这里为五个方块分别设置不同时序函数,作为比较进行展示
橙色: 默认ease; 黄色:加速ease-in;
粉色: 匀速linear; 绿色: 减速ease-out
蓝色: 先加速再减速ease-in-out;
1.2.4. 实例4 通过贝塞尔曲线设置时序的动画
transition-timing-function:cubic-bezier(.69,1.77,.25,-0.84)
1.2.5. 实例5 分步执行过渡效果
#box{
height:300px;
width:800px;
background-color:#fff;
overflow:hidden;
font-size:5px;
}
#box1{
height:50px;
width:50px;
background-color:#FF8A65;
margin-top:5px;
margin-left:30px;
/* 过渡属性 */
transition-property:all;
transition-duration:1.5s;
transition-timing-function:steps(5) // 将1.5秒平分为5份
}
#box:hover #box1{
margin-left:400px;
}
// steps(5,start) 这是设置动画开始时间,默认为end,即该情景下0.5秒之后再开始
// 但start属性是直接开始
🚞2. 动画
动画(animation)与过渡类似,都是可以实现一些动态的效果,不同的是
- 过渡需要在某个属性发生变化时才会触发
- 动画可以自动触发动态效果
官方文档: 1. animation- CSS: 叠层样式表 | MDN 2. 使用 CSS 动画
2.1. 属性值
2.1.1. animation-name
animation-name 用于指定应用的一系列动画,每个名称代表一个由@keyframes 定义的动画序列。
@keyframes 通过在动画序列中定义关键帧的样式来控制 CSS 动画序列中的中间步骤。和转换 transition 相比,关键帧 keyframes 可以控制动画序列的中间步骤。
/* 语法 */
animation-name: 动画名称
/* 取值 */
none: 特殊关键字,表示无关键帧
动画名称: 自定义的关键帧名字
/* 示例 */
@keyframes magnify {
/* 动画开始位置 也可以使用 0%*/
from{ width:10px;height:10px; }
/* 动画结束位置 也可以使用 100%*/
to{ width:20px;height:20px; }
}
.box{ /* 设置动画 */
animation-name: magnify ;
}
/* 注意 */
1.如果多个关键帧使用同一个名称,以最后一次定义的为准。
2.如果某一个关键帧出现了重复的定义,且重复的关键帧中的 CSS 属性值不同,
则以最后一次定义的属性为准。
3.关键帧中出现的 !important 将会被忽略。
2.1.2. animation-duration
animation-duration 用于设置动画完成一个动画周期所需的时间。
/* 语法 */
animation-duration: 动画名称
/* 取值 */
<time>类型
/* 示例 */
animation-duration: 3s;
animation-duration: 1s 2s 3s;
/* 注意 */
需要对多个动画设置时间时,用 , 隔开(如示例2)
2.1.3. 其他属性
(1)animation-delay:动画效果的延迟,等待一段时间后再执行动画
/* 语法 */
animation-delay: 延迟时长
/* 取值 */
<time>类型
/* 示例 */
animation-delay: 3s;
(2)animation-timing-function:动画的时序函数,与transition-timing-function取值和用法一致,这里不再说明
(3)animation-iteration-count :动画执行的次数
/* 语法 */
animation-iteration-count: 执行次数
/* 取值 */
<number>类型: 默认为 1。可以指定非整数值以播放动画循环的一部分:
例如,0.5 将播放动画循环的一半。负值是无效的。
infinite: 无限循环播放动画
/* 示例 */
animation-iteration-count: 3.5;
animation-iteration-count: 2, 0, infinite;
/* 注意 */
属性可以指定一个或多个以逗号分隔的值。
(4)animation-direction :指定动画运行的方向
/* 语法 */
animation-iteration-count: 运行方向
/* 取值 */
normal: 每个循环内动画向前循环,换言之,每个动画循环结束,
动画重置到起点重新开始,这是默认属性。
alternate: 动画交替反向运行,反向运行时,动画按步后退,
同时,带时间功能的函数也反向,比如,ease-in 在反向时成为
ease-out。计数取决于开始时是奇数迭代还是偶数迭代
reverse: 反向运行动画,每周期结束动画由尾到头运行。
alternate-reverse: 反向交替,反向开始交替。动画第一次运行时是反向的,
然后下一次是正向,后面依次循环。
决定奇数次或偶数次的计数从 1 开始。
/* 示例 */
animation-direction: normal;
animation-direction: alternate, reverse, normal;
/* 注意 */
属性可以指定一个或多个, 并以逗号分隔。
(5)animation-play-state :设置动画的执行状态
- 即:设置动画是运行还是暂停
/* 语法 */
animation-play-state: 执行状态
/* 取值 */
running: 当前动画正在运行。
paused: 当前动画已被停止。
/* 示例 */
animation-play-state: paused;
animation-play-state: paused, running, running;
/* 注意 */
属性可以指定一个或多个, 并以逗号分隔。
(6)animation-fill-mode :动画的填充模式
- 即:设置 CSS 动画在执行之前和之后如何将样式应用于其目标
/* 语法 */
animation-fill-mode: 填充模式
/* 取值 */
none: 动画执行完毕,元素回到原来位置,默认值
forwards: 动画执行完毕,元素会停止在动画结束的位置
backwards: 动画延时等待时,元素就会处于开始位置
both: 结合了forwards和backwards
/* 示例 */
animation-fill-mode: backwards;
animation-fill-mode: both, forwards, none;
/* 注意 */
属性可以指定一个或多个, 并以逗号分隔。
2.1.4. 注意
上述属性可以独立使用,也可以全部写在属性animation里
/* 语法 */
animation: 属性1, 属性2, ... , 属性n
/* 示例 */
animation: moveDiv, 2s, infinite ,forwards;
/* 等同于 */
{
animation-name: moveDiv;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-fill-mode: backwards;
}
2.2. 实例
2.2.1. 实例6 多属性动画效果
使用到的属性
animation-name: test; 关键帧test
animation-duration: 2s; 动画一次执行2s
animation-fill-mode: forwards; 元素会停止在动画结束的位置
animation-iteration-count: infinite; 循环执行
animation-direction: alternate; 从结束位置返回
animation-play-state:paused; 鼠标悬浮暂停动画,增强互动
#box1{
height:50px;
width:50px;
background-color:rgb(200,230,201,0);
/* 设置动画属性 */
animation-name:test;
animation-duration:2s;
animation-fill-mode:forwards;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#box1:hover{
/* 改变元素状态 */
animation-play-state:paused;
}
@keyframes test{
from{
margin-left:0px;
}
to{
margin-left:200px;
background-color:#C8E6C9;
}
}
2.2.2. 实例7 行走动画
![]() | ![]() |
---|
这里使用的图片里有四个等大的人物元素,因为要实现行走效果,我们可以设置steps(4)来实现,下面的代码是用过渡(transition)属性来实现的,大家可以试试用动画(添加关键帧)来实现,方法大同小异。
- 将整个图片作为子元素div的背景,同时设置父元素(id=“box”)的overflow属性为hidden
- 将图片四等分,即每一步只显示一个元素宽度的背景
- 编写关键帧,即动画从第一个元素开始执行,结束时图片背景到达最后一个元素
- 如上方右图,看似动画是向右行进,但我们以固定的绿色实线方框(子元素div id=“box1”)来看,其实动画的实现是背景在向左移动,并分四步完成
#box{
height:300px;
width:800px;
background-color:#fff;
overflow:hidden;
font-size:5px;
}
#box1{
height:38px;
width:25px;
background-image:url('https://s1.chu0.com/src/img/png/b9/b94c91a38bce48078872b1e2e8e00e33.png');
margin-top:5px;
margin-left:30px;
background-position:0 74;//动作起始位置
transition: background-position 1s steps(4);
}
#box:hover #box1{
background-position:-100 74;//动作结束时在图片中的位置
}
2.2.3. 实例8 奔跑动画
这里的实现与实例7方法一致,只是采用animation来实现并缩减了动画执行的时间,动作更连贯。
.box1{
height:140px;
width:108px;
background-image:url('https://blaiprat.github.io/jquery.animateSprite/img/scottpilgrim_multiple.png');
margin-top:5px;
margin-left:30px;
animation: run 1s steps(8) infinite;
}
@keyframes run {
from {
background-position: 0 0;
}
to {
background-position: -864px 0;
}
}
2.2.4. 实例9 fulldown
实例9 将动画中间步骤细分,使小球实现落地回弹效果
.box{
height:300px;
border-bottom:5px rgb(25,77,51,.5) solid;
overflow:hidden
}
.box1{
height:50px;
width:50px;
border-radius:50%;
/* 小球背景渐变色 */
background-image: radial-gradient(ellipse at top,#FFCCBC, transparent),
radial-gradient(ellipse at bottom, #AED581, transparent);
margin-left:30px;
animation: fulldown 1s forwards ease-in;
}
@keyframes fulldown {
from {
margin-top:5px;
}
20%,60%,to{
margin-top:250px;
animation-timing-function: ease-in
}
40%{
margin-top:220px;
}
80%{
margin-top:240px;
}
}
2.2.5. 实例10 波动效果
这里统一为小球设置动画效果,每个小球再分别延迟1s执行,以实现波动效果,这展示了第二个小球(id=“box1”)的css样式
div{ /*统一设置小球样式*/
margin-top:20px;
float: left;
height:50px;
width:50px;
border-radius:50%;
animation: fulldown 1s forwards ease-in infinite alternate;
}
.box1{
background-color :#E57373;
margin-left:30px;
animation-delay: .1s; /*后面每一个小球分别延迟1秒*/
}
@keyframes fulldown {
from {
margin-top:20px;
}
to{
margin-top:200px;
}
}
🛸3. 变换
变换(transform)属性用于旋转,缩放,倾斜或平移给定元素。这是通过修改 CSS 视觉格式化模型的坐标空间来实现的。需要注意的是:变形不会影响到页面的布局
官方文档: 1. transform- CSS: 叠层样式表 | MDN 2. 使用CSS 变换
3.1. 属性值
3.1.1. translate平移
通过 translate 可以使元素沿着x、y或z平移指定的距离。可以单独声明平移变换,并独立于 transform 属性。
/* 不独立声明 */
/* 使用 */
transform: translateX(10px);
/* 取值 */
translateX() 沿着x轴方向平移
translateY() 沿着y轴方向平移
translateZ() 沿着z轴方向平移
/* 独立声明 */
/* 使用 */
translate: 105px;
/* 取值 */
1. 一个长度值或百分比,表示二维平移,与声明了 X 轴和 Y 轴的平移一样(此时省略的第二个值默认为 0)
2. 两个长度值或百分比表示在二维上分别按照指定 X 轴和 Y 轴的值进行的平移
3. 三个长度值或百分比,表示分别指定 X 轴、Y 轴、Z 轴的值进行三维平移
3.1.2. rotate旋转
通过 rotate 可以使元素沿着x、y或z旋转指定的角度。可以单独声明,并独立于 transform 属性。
/* 不独立声明 */
/* 使用 */
transform: rotateY(180deg);
/* 取值 */
rotateX() 绕着x轴方向旋转
rotateY() 绕着y轴方向旋转
rotateZ() 绕着z轴方向旋转
/* 独立声明 */
/* 使用 */
rotate: 90deg;
/* 取值 */
1. 角度值
deg: 度 一个完整的圆是 360deg
grad: 百分度 一个完整的圆是 400grad
rad: 弧度 一个完整的圆是 2π 弧度 , 1rad 是 180/π 度
turn: 圈数 一个完整的圆是 1turn
2. x, y 或者 z 轴名称加上角度值
rotate: x 90deg;
rotate: y 0.25turn;
rotate: z 1.57rad;
3. 向量加上角度值
4. none
3.1.3. scale缩放
通过 scale 可以对元素进行缩放。
/* 使用 */
transform: scale(2);
/* 取值 */
scaleX() 水平方向缩放
scaleY() 垂直方向缩放
scale() 双方向的缩放
3.2. 实例
3.2.1. 实例11 简单浮动效果
当鼠标悬停在卡片上时,修改卡片属性,使其看起来像悬浮起来一样
- 向y轴平移5px
- 添加阴影
当然可以将阴影设置更深,效果更佳
动手试一试
div {
float: left;
width: 200px;
height: 300px;
background-color: silver;
margin: 100px 50px auto 50px;
transition: all .3s;
}
div:hover {
box-shadow: 0 0 10px rgba(0, 0, 0, .2);
transform: translateY(-5px);
}
3.2.2. 实例12 简单翻转效果
/* transform: rotateY(0.5turn); */
.card:hover{
transform: rotateY(180deg);
}
3.2.3. 实例13 简单缩放效果
![]() | ![]() |
---|
我们只需要设置两个属性即可
- 缩放变形的原点,默认(0,0)
- 缩放的倍数
.box {
height: 200px;
width: 200px;
background-color: #bfa;
margin: 200px auto;
transition: 2s;
}
.box:hover {
/* transform: scaleX(2); */
/* transform: scaleY(2); */
transform: scale(2);
/* 变形的原点 */
transform-origin: 0 0;
}
3.2.4. 实例14 时钟效果
这里我们先统一设置时分秒三个指针的动画
- 即 绕着z轴(垂直于屏幕向外的轴)从0°到360°转动一圈
- 并循环执行
接下来再分别为三个指针设置单独的动画属性
- 即 三个指定对应执行的时间(时针: 216000s 分针: 3600s 秒针: 60s)
- 以及设置分步执行的时序函数(也可以不设置,这样看起来就更流畅)
<div class="clock">
<div class="hour-wrapper">
<div class="hour"></div>
</div>
<div class="minute-wrapper">
<div class="minute"></div>
</div>
<div class="second-wrapper">
<div class="second"></div>
</div>
</div>
.clock {
width: 500px;
height: 500px;
border-radius: 50%;
background-image: url("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fp8.itc.cn%2Fq_70%2Fimages03%2F20200826%2F810dd25ef3e4495d9cbdde3035224f2e.png&refer=http%3A%2F%2Fp8.itc.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1660128671&t=840042b01abffb7274270b2b5420fd01");
background-size: cover;
margin: 100px auto;
position: relative;
}
.clock>div {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
.clock>div>div {
height: 50%;
margin: 0 auto;
}
/* 时针 */
.hour-wrapper {
height: 60%;
width: 60%;
animation: clock-run 216000s infinite;
}
.hour {
width: 8px;
background-color: black;
}
/* 分针 */
.minute-wrapper {
height: 75%;
width: 75%;
animation: clock-run 3600s steps(60) infinite;
}
.minute {
width: 4px;
background-color: black;
}
/* 秒针 */
.second-wrapper {
height: 90%;
width: 90%;
animation: clock-run 60s steps(60) infinite;
}
.second {
width: 2px;
background-color: white;
}
@keyframes clock-run {
from {
transform: rotateZ(0);
}
to {
transform: rotateZ(360deg);
}
}
3.2.5. 实例15 3D旋转效果
这里效果动态图超过可上传文件大小,只能通过链接展示
效果展示
<div class="cube">
<div class="surface1"></div>
<div class="surface2"></div>
<div class="surface3"></div>
<div class="surface4"></div>
<div class="surface5"></div>
<div class="surface6"></div>
</div>
html {
perspective: 800px;
}
.cube {
height: 200px;
width: 200px;
margin: 200px auto;
position: relative;
/* 设置3d变形效果 */
transform-style: preserve-3d;
animation: cube-rotate 17s infinite linear;
}
.cube div {
height: 200px;
width: 200px;
background-size: cover;
position: absolute;
top: 0;
left: 0;
/* 为元素设置透明效果 */
opacity: .85;
}
.surface1 {
background-image: url("https://img1.baidu.com/it/u=291669987,694598207&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=478");
transform: translateX(-100px) rotateY(90deg);
}
.surface2 {
background-image: url("https://img2.baidu.com/it/u=2225197824,456648332&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500");
transform: translateX(100px) rotateY(90deg);
}
.surface3 {
background-image: url("https://img0.baidu.com/it/u=1942349810,1332231219&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500");
transform: translateY(-100px) rotateX(90deg);
}
.surface4 {
background-image: url("https://img2.baidu.com/it/u=4028899442,1114534948&fm=253&fmt=auto&app=138&f=JPEG?w=502&h=500");
transform: translateY(100px) rotateX(90deg);
}
.surface5 {
background-image: url("https://img1.baidu.com/it/u=4094157639,241767820&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501");
transform: translateZ(-100px);
}
.surface6 {
background-image: url("https://img0.baidu.com/it/u=4123557952,4240437061&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500");
transform: translateZ(100px);
}
@keyframes cube-rotate {
from {
transform: rotateX(0) rotateY(0) rotateZ(0);
}
to {
transform: rotateX(1turn) rotateY(2turn) rotateZ(3turn);
}
}
🥰文章到这里就结束啦,感谢大家看到这里,喜欢的朋友可以点赞收藏哦
🤗文中出现的图片如有侵权,一定会立即删除的
🤩文章有误的地方欢迎大家批评指正,一起加油!