css动画

目录

transform

transform 属性

transition

transition 生效条件

transition 不生效的条件

will-change 的作用

JavaScript 监听动画结束

transition 推荐和 transform 配合使用

transition 属性

@keyframes

animation 属性

案例

理解 steps 属性、单行

理解 steps 属性、多行换行

理解 step-end 属性、单行

理解 step-end 属性、多行换行

植物大战僵尸


CSS 动画是指使用 CSS 规则让网页元素实现动态变化的效果,例如平移、旋转、缩放、颜色变化等,而无需 JavaScript。

transform

transform 用于2D/3D 变换,对元素进行 旋转(rotate)、缩放(scale)、倾斜(skew)、移动(translate) 等变换。
它不会影响周围元素的布局,而是直接修改元素的视觉表现。

transform 属性

变换类型函数说明
平移translate(x, y)沿 X、Y 轴移动
旋转    rotate(angle)  围绕原点旋转,顺时针正数,逆时针负数,单位deg度
缩放    scale(x, y)   沿 X、Y 轴缩放
倾斜     skew(x-angle, y-angle)  沿 X、Y 轴倾斜
矩阵    matrix(a, b, c, d, e, f)    

直接定义 2D 变换矩阵

a:X 轴的缩放系数。
b:X 轴的倾斜。
c:Y 轴的倾斜。
d:Y 轴的缩放系数。
e:X 轴的平移。
f:Y 轴的平移。

3D 平移   translate3d(x, y, z)   x:沿 X 轴(水平方向)平移的距离。
y:沿 Y 轴(垂直方向)平移的距离。
z:沿 Z 轴(深度方向,表示前后平移)的距离。
3D 旋转rotate3d(x, y, z, angle)x:旋转轴 X 的方向(通常为 0 或 1),表示旋转是否绕 X 轴进行。
y:旋转轴 Y 的方向(通常为 0 或 1),表示旋转是否绕 Y 轴进行。
z:旋转轴 Z 的方向(通常为 0 或 1),表示旋转是否绕 Z 轴进行。
angle:旋转的角度,单位是度(deg),常见的值为 90deg、180deg 等。
3D 缩放scale3d(x, y, z)x:沿 X 轴 缩放的比例。
y:沿 Y 轴 缩放的比例。
z:沿 Z 轴 缩放的比例。
3D 视觉效果perspective(distance)

设置视点距离元素的深度距离,单位通常是像素(px)或者其他长度单位(如 em、rem 等)。这个距离值决定了透视效果的强度。

100px:透视过强,可能导致元素消失

300px:透视较强,元素有明显 3D 效果

500px:适中,3D 效果自然

1000px:透视较弱,元素移动时变化较小

变换中心点

transform-origin

设置 CSS 变换的原点,默认是元素的中心(50% 50%)

左上角:(0% 0%) left top
左下角:(0% 100%) left bottom
右上角:(100% 0%) right top
右下角:(100% 100%) right bottom

隐藏背面

backface-visibility

visible(默认):背面可见,元素翻转后仍然能看到背面内容
hidden:背面不可见,元素翻转 180° 后完全隐藏
保留3D效果transform-style

是否保留子元素的 3D 变换效果。

flat(默认):子元素不继承 3D 变换,所有子元素在 2D 平面上
preserve-3d:保留子元素的 3D 变换效果,子元素可以独立在 3D 空间中移动


translate 平移示例代码

<style>
    .container {
        width: 300px;
        height: 200px;
        border: 2px dashed gray;
    }
    
    .box {
        width: 100px;
        height: 100px;
        background-color: skyblue;
        text-align: center;
        line-height: 100px;
    }

    /* 鼠标悬停 */
    .box:hover {
        /* 沿 X、Y 轴移动 */
        transform: translate(50px, 20px);
    }
</style>

<h3>transform: translate() 示例</h3>
<p>鼠标悬停在蓝色方块上时,它会向右移动 50px,向下移动 20px</p>
<div class="container">
    <div class="box">移动我</div>
</div>

效果图


translate3d 3D平移示例代码

<style>
    .container {
        /* 设置透视效果,增强 3D 视觉 */
        perspective: 500px;
        width: 300px;
        height: 200px;
        border: 2px dashed gray;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    
    .box {
        width: 100px;
        height: 100px;
        background-color: skyblue;
        text-align: center;
        line-height: 100px;
        /* 这个是动画效果 */
        transition: transform 0.5s ease-in-out;
    }
    
    .box:hover {
        /* X 右移 50px,Y 下移 20px,Z 轴前移 100px */
        transform: translate3d(50px, 20px, 100px);
    }
</style>

<h3>transform: translate3d() 示例</h3>
<p>鼠标悬停在蓝色方块上时,它会在三维空间移动。</p>
<div class="container">
    <div class="box">3D 移动</div>
</div>

效果图


rotate 旋转示例代码

<style>
    .container {
        width: 300px;
        height: 200px;
        border: 2px dashed gray;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    
    .box {
        width: 100px;
        height: 100px;
        background-color: skyblue;
        text-align: center;
        line-height: 100px;
        font-weight: bold;
        /* 这是动画效果 */
        /* transition: transform 0.5s ease-in-out; */
    }
    
    .box:hover {
        /* 顺时针旋转 45° ,逆时针就负数*/
        transform: rotate(45deg);
    }
</style>

<h3>transform: rotate() 示例</h3>
<p>鼠标悬停在蓝色方块上时,它会顺时针旋转 45°</p>
<div class="container">
    <div class="box">旋转我</div>
</div>

效果图


rotate3d 3d旋转示例代码

rotate3d(x, y, z),可以用 rotateX、rotateY、rotateZ 代替

<style>
    .container {
        width: 450px;
        height: 250px;
        border: 2px dashed gray;
        display: grid;
        grid-template-columns: 1fr 1fr 1fr 1fr;
        grid-template-rows: 1fr 1fr;
        align-items: center;
        justify-content: center;
        gap: 10px;
        padding: 10px;
    }
    
    .container div {
        width: 100px;
        height: 100px;
        background-color: skyblue;
        text-align: center;
        line-height: 100px;
        /* 动画效果 */
        transition: transform 0.5s ease-in-out;
    }
    
    .box1:hover {
        /* 绕 X、Y、z 轴旋转 */
        transform: rotate3d(0, 0, 1, 80deg);
    }
    
    .box2:hover {
        /* 绕 X、Y、z 轴旋转 */
        transform: rotate3d(0, 1, 0, 80deg);
    }
    
    .box3:hover {
        /* 绕 X、Y、z 轴旋转 */
        transform: rotate3d(0, 1, 1, 80deg);
    }
    
    .box4:hover {
        /* 绕 X、Y、z 轴旋转 */
        transform: rotate3d(1, 0, 0, 80deg);
    }
    
    .box5:hover {
        /* 绕 X、Y、z 轴旋转 */
        transform: rotate3d(1, 0, 1, 80deg);
    }
    
    .box6:hover {
        /* 绕 X、Y、z 轴旋转 */
        transform: rotate3d(1, 1, 0, 80deg);
    }
    
    .box7:hover {
        /* 绕 X、Y、z 轴旋转 */
        transform: rotate3d(1, 1, 1, 80deg);
    }
</style>

<h3>CSS transform: rotate3d() 示例</h3>
<p>鼠标悬停在蓝色方块上时,它会在 3D 空间绕 X、Y、Z 轴旋转。</p>
<div class="container">
    <div class="box1">3D 旋转1</div>
    <div class="box2">3D 旋转2</div>
    <div class="box3">3D 旋转3</div>
    <div class="box4">3D 旋转4</div>
    <div class="box5">3D 旋转5</div>
    <div class="box6">3D 旋转6</div>
    <div class="box7">3D 旋转7</div>

</div>

效果图


scale 缩放示例代码

<style>
    .container {
        width: 300px;
        height: 200px;
        border: 2px dashed gray;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    
    .box {
        width: 100px;
        height: 100px;
        background-color: lightblue;
        text-align: center;
        line-height: 100px;
        /* 动画效果 */
        transition: transform 0.5s ease-in-out;
    }
    
    .box:hover {
        /* X 轴缩小 0.5 倍,Y 轴放大 1.5 倍 */
        transform: scale(0.5, 1.5);
    }
</style>

<h3>CSS transform: scale() 示例</h3>
<p>鼠标悬停在蓝色方块上时,它会在 X 轴缩小 0.5 倍,Y 轴放大 1.5 倍</p>
<div class="container">
    <div class="box">缩放我</div>
</div>

效果图


scale3d 和 scale 类似,示例同上


skew 倾斜代码示例

<style>
    .container {
        width: 300px;
        height: 200px;
        border: 2px dashed gray;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    
    .box {
        width: 100px;
        height: 100px;
        background-color: skyblue;
        text-align: center;
        line-height: 100px;
        /* 动画效果 */
        transition: transform 0.5s ease-in-out;
    }
    
    .box:hover {
        /* X 轴倾斜 30°,Y 轴倾斜 15° */
        transform: skew(30deg, 15deg);
    }
</style>

<h3>CSS transform: skew() 示例</h3>
<p>鼠标悬停在蓝色方块上时,它会倾斜。</p>
<div class="container">
    <div class="box">倾斜我</div>
</div>

效果图


matrix 矩阵示例代码

<style>
    .container {
        width: 350px;
        height: 250px;
        margin-left: 10px;
        border: 2px dashed gray;
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
        grid-template-rows: 1fr 1fr;
        align-items: center;
        justify-content: center;
        gap: 10px;
        padding: 10px;
    }
    
    .container div {
        width: 100px;
        height: 100px;
        text-align: center;
        line-height: 100px;
        /* 动画效果 */
        transition: transform 0.5s ease-in-out;
    }
    
    .box1:hover {
        /* 复合变换 */
        transform: matrix(1, 0.5, -0.5, 1, 50, 100);
    }
    
    .box2:hover {
        /* 复合变换 */
        transform: matrix(1.5, 0.2, -0.2, 1.5, 150, 50);
    }
    
    .box3:hover {
        /* 复合变换 */
        transform: matrix(1, 1, 0, 1, 100, 100);
    }
    
    .box4:hover {
        /* 复合变换 */
        transform: matrix(2, -0.5, 0.5, 2, 50, 150);
    }
    
    .box5:hover {
        /* 复合变换 */
        transform: matrix(1, 0, 0, 1, 100, 100);
    }
</style>

<h3>CSS transform: matrix() 示例</h3>
<p>鼠标悬停在蓝色方块上时,元素将进行复合变换。</p>
<div class="container">
    <div class="box1" style="background-color:cadetblue">变换我1</div>
    <div class="box2" style="background-color:brown">变换我2</div>
    <div class="box3" style="background-color:blueviolet">变换我3</div>
    <div class="box4" style="background-color:seagreen">变换我4</div>
    <div class="box5" style="background-color:silver">变换我5</div>
</div>

效果图


组合示例

.box:hover {
    /* 平移、旋转、放大 */
    transform: translate(50px, 20px) rotate(45deg) scale(1.5);
}

transform-origin 变换中心点示例代码

默认情况下,transform-origin 可能只有在 hover 时生效,返回时恢复默认(50% 50%),导致动画不连贯。因此,你需要在默认状态也定义 transform-origin。

<style>
    body {
        margin-left: 100px;
    }

    .container {
        width: 350px;
        height: 250px;
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
        grid-template-rows: 1fr 1fr;
        align-items: center;
        justify-content: center;
        gap: 10px;
        padding: 10px;
    }

    .box {
        width: 100px;
        height: 100px;
        background-color: skyblue;
        text-align: center;
        line-height: 100px;
        font-weight: bold;
        /* 动画效果 */
        transition: transform 0.5s ease-in-out;
    }

    /* 变换示例 */
    .box1 {
        /* 设置默认变换点状态 */
        transform-origin: left top;
    }

    .box1:hover {
        /* 设置鼠标移动上去时的变化中心点 */
        transform-origin: left top;
        /* 旋转 45度 */
        transform: rotate(45deg);
    }

    .box2 {
        /* 设置默认变换点状态 */
        transform-origin: right top;
    }

    .box2:hover {
        /* 设置鼠标移动上去时的变化中心点 */
        transform-origin: right top;
        transform: rotate(45deg);
    }

    .box3 {
        /* 设置默认变换点状态 */
        transform-origin: left bottom;
    }

    .box3:hover {
        /* 设置鼠标移动上去时的变化中心点 */
        transform-origin: left bottom;
        transform: rotate(45deg);
    }

    .box4 {
        /* 设置默认变换点状态 */
        transform-origin: right bottom;
    }

    .box4:hover {
        /* 设置鼠标移动上去时的变化中心点 */
        transform-origin: right bottom;
        transform: rotate(45deg);
    }

    .box5 {
        /* 设置默认变换点状态 */
        transform-origin: center;
    }

    .box5:hover {
        /* 设置鼠标移动上去时的变化中心点 */
        transform-origin: center;
        transform: rotate(45deg);
    }

    .box6 {
        /* 设置默认变换点状态 */
        transform-origin: 30% 70%;
    }

    .box6:hover {
        /* 设置鼠标移动上去时的变化中心点 */
        transform-origin: 30% 70%;
        transform: rotate(45deg);
    }
</style>


<body>
    <h3>CSS transform-origin 示例</h3>
    <p>鼠标悬停在方块上,观察不同的变换基准点。</p>
    <div class="container">
        <div class="box box1">左上角</div>
        <div class="box box2">右上角</div>
        <div class="box box3">左下角</div>
        <div class="box box4">右下角</div>
        <div class="box box5">中心</div>
        <div class="box box6">30% 70%</div>
    </div>
</body>

效果图


backface-visibility: hidden 隐藏背面示例

<style>
    .container {
        width: 300px;
        height: 200px;
        border: 2px dashed gray;
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .box {
        width: 100px;
        height: 100px;
        background-color: skyblue;
        text-align: center;
        line-height: 100px;
        font-weight: bold;
        /* 这是动画效果 */
        transition: transform 0.5s ease-in-out;
        /* 隐藏背面 */
        backface-visibility: hidden;
    }

    .box:hover {
        /* 旋转 Y 轴 180度 */
        transform: rotateY(180deg);
    }
</style>

<h3>transform: rotateY() 示例</h3>
<p>鼠标悬停在蓝色方块上时,它会在 Y 轴旋转 180° 后让背面不可以见</p>
<div class="container">
    <div class="box">旋转我</div>
</div>

效果图


backface-visibility: hidden 隐藏背面 实战示例

<style>
    .container {
        /* 3D 立体效果,营造出在 3D空间一样的环境 */
        perspective: 1000px;
        /* ---------------- 以下是普通 CSS 样式 ---------------- */
        width: 200px;
        height: 300px;
        margin: 50px;
    }

    .card {
        /* 动画效果 */
        transition: transform 1s;
        /* 让子元素保留3D效果,不然看到不到背面 */
        transform-style: preserve-3d;
        /* ---------------- 以下是普通 CSS 样式 ---------------- */
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .card:hover {
        /* 鼠标悬停时 Y 轴翻转 180 度 */
        transform: rotateY(180deg);
    }

    .box1 {
        /* 隐藏背面  */
        backface-visibility: hidden;
        /* 绝对定位,让2个div重叠在一起 */
        position: absolute;
        /* ---------------- 以下是普通 CSS 样式 ---------------- */
        width: 100%;
        height: 100%;
        background-color: skyblue;
        border-radius: 10px;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 20px;
        font-weight: bold;
    }

    .box2 {
        /* 隐藏背面  */
        backface-visibility: hidden;
        /* 背面 div 直接默认翻转 180 度。相当于在一个立体空间,2个人背靠背 */
        transform: rotateY(180deg);
        /* ---------------- 以下是普通 CSS 样式 ---------------- */
        width: 100%;
        height: 100%;
        background-color: lightcoral;
        border-radius: 10px;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 20px;
        font-weight: bold;
    }
</style>
<div class="container">
    <div class="card">
        <div class="box1">正面</div>
        <div class="box2">背面</div>
    </div>
</div>

效果图


transition

transition 用于控制元素状态变化时的过渡动画的属性。它由多个子属性组成,分别控制不同的动画行为。

transition 生效条件

  • :hover(鼠标悬停)
  • :focus(表单获取焦点)
  • :active(元素被点击)
  • 通过 JavaScript 修改样式

不是所有 CSS 属性都能使用 transition,只有数值型的属性才可以

  • 颜色属性(color, background-color, border-color)
  • 大小属性(width, height, max-width, max-height)
  • 透明度(opacity)
  • 位置(top, left, right, bottom, transform)

transition 不生效的条件

  • display(布局)
  • visibility(站位可见性)
  • position(定位)
  • z-index(堆叠顺序)
  • 初始值和目标值相同
  • 页面渲染未完成之前

will-change 的作用

  • will-change 告诉浏览器某个属性即将发生变化,使其提前进行优化,从而减少卡顿。
  • 适用于 transition 频繁变化的场景,比如 hover 或 scroll 触发的动画。
  • 注意:不要滥用 will-change,否则可能会占用大量 GPU 资源,导致页面变慢。
  • auto:默认值,浏览器自行优化
  • transform:提示即将有 transform 变换
  • opacity:提示即将有透明度变化
  • scroll-position:提示即将有滚动变化
  • contents:提示即将改变 content(布局)
  • unset:取消 will-change
    <style>
        .box {
            transition: transform 0.5s;
            /* 提前告诉浏览器即将发生 transform 变化 */
            will-change: transform;
        }
    
        .box:hover {
            transform: scale(1.5);
        }
    </style>

JavaScript 监听动画结束

<script>
    const box = document.querySelector('.box');
    box.addEventListener('transitionend', () => {
        console.log('动画已结束!');
    });
</script>

transition 推荐和 transform 配合使用

transition 属性

transition: property duration timing-function delay;

  • transition-property:指定要应用过渡效果的 CSS 属性
    • all:所有可过渡的属性都应用动画(默认)。
    • none:不应用过渡效果。
    • 指定属性,如 background-color, width, opacity 等。
      div {
          transition-property: background-color, width;
      }
      
  • transition-duration:设置过渡动画持续的时间,单位ms或s
    div {
        transition-duration: 0.5s, 1s;
    }
    
    /* 第一个属性(如 background-color)的过渡时间是 0.5s */
    /* 第二个属性(如 width)的过渡时间是 1s */
    
  • transition-timing-function:设定动画的时间曲线(加速/减速方式)
    • ease(默认):开始和结束时慢,中间快。
    • ease-in:动画开始时慢,随后加速。
    • ease-out:动画开始时快,随后减速。
    • ease-in-out:动画开始和结束时慢,中间快。
    • linear:匀速变化。
    • cubic-bezier(n,n,n,n):自定义贝塞尔曲线。
      div {
          transition-timing-function: ease-in-out;
      }
      
  • transition-delay:设置动画开始前的延迟时间,单位ms或s
    div {
        transition-delay: 0.3s;
    }

all 代码示例

<style>
    .container {
        width: 300px;
        height: 200px;
        border: 2px dashed gray;
    }

    .box {
        width: 100px;
        height: 100px;
        background: lightblue;
        transition: all 0.5s ease;
    }

    .box:hover {
        width: 150px;
        height: 150px;
        background: tomato;
    }
</style>

<h3>transition: all 示例</h3>
<p>transition 对所有属性都生效</p>
<div class="container">
    <div class="box"></div>
</div>

效果图


opacity 透明度 代码示例

<style>
    .container {
        width: 300px;
        height: 200px;
        border: 2px dashed gray;
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .box {
        width: 100px;
        height: 100px;
        background: skyblue;
        transition: opacity 0.5s ease;
    }

    .box:hover {
        opacity: 0;
    }
</style>

<h3>transition: opacity 示例</h3>
<p>鼠标悬停时,元素 渐渐消失。</p>
<div class="container">
    <div class="box"></div>
</div>

效果图


展开/折叠 代码示例

<style>
    .container {
        width: 220px;
    }

    .toggle-btn {
        display: block;
        width: 100%;
        padding: 10px;
        background: steelblue;
        color: white;
        /* 移除边框效果 */
        border: none;
        /* 小手鼠标样式 */
        cursor: pointer;
        text-align: center;
        font-size: 16px;
        margin-bottom: 5px;
        border-radius: 5px;
    }

    .toggle-btn:hover {
        background: darkblue;
    }

    /* 折叠状态 */
    .box {
        width: 200px;
        background: lightblue;
        /* 初始高度为 0 */
        max-height: 0;
        /* 隐藏溢出部分 */
        overflow: hidden;
        /* 过渡动画 */
        transition: max-height 0.5s ease;
        /* 避免内容溢出时产生不自然的动画 */
        padding: 0 10px;
    }

    /* 展开状态 */
    .box.open {
        /* 设置足够大的高度,确保内容能展开 */
        max-height: 200px;
        /* 展开时增加内边距 */
        padding: 0 10px;
    }
</style>

<div class="container">
    <button class="toggle-btn">切换展开/折叠</button>
    <div class="box">
        <p>这是可折叠的内容。点击按钮可以展开或折叠。</p>
        <p>你可以放入任何内容,如文本、图片、表格等。</p>
    </div>
</div>

<script>
    const button = document.querySelector('.toggle-btn');
    const box = document.querySelector('.box');

    button.addEventListener('click', () => {
        // 切换 `open` 类名,实现展开/折叠,toggle:class存在时移除,不存在时添加
        box.classList.toggle('open');
    });
</script>

效果图

transition + transform 配合 示例代码

<style>
    .box {
        width: 100px;
        height: 100px;
        margin-top: 100px;
        background-color: #3498db;
        /* 动画效果,使用 transform */
        transition: transform 1s ease;
    }

    /* :hover 鼠标悬停时 */
    .box:hover {
        /* 移动并旋转 */
        transform: translate(200px, 0) rotate(720deg);

    }
</style>

<div class="box"></div>

@keyframes

@keyframes 用于定义动画关键帧的规则,它允许你创建复杂的动画效果。

语法:

@keyframes 自定义动画名称 {
    0% { 初始状态 }            /* 第一个关键帧 */
    100% { 结束状态 }          /* 第二个关键帧 */
}

或者

@keyframes 自定义动画名称 {
    from { 初始状态 }
    to { 结束状态 }
}

animation 属性

animation:应用 @keyframes 动画到 HTML 元素上。

语法:

animation: name duration timing-function delay iteration-count direction fill-mode;

参数说明:

  • name:指定动画的名字,必须和 @keyframes 中定义的名字一致。
  • duration:动画持续时间,指定动画从开始到结束的时间。单位可以是 s(秒)或 ms(毫秒)。
  • timing-function:定义动画的缓动函数,决定动画在时间轴上如何变化。
    • linear:动画的速度从头到尾始终均匀,速度不会发生变化。
    • ease (默认值):动画开始时慢,接着加速,最后再减速。
    • ease-in:动画开始时较慢,然后逐渐加速。
    • ease-out:动画开始时加速,最后逐渐减速。
    • ease-in-out:动画开始和结束时都较慢,中间部分加速。
    • steps(n, start | end):通过指定一个步数来控制动画的分步进行,适用于精灵图等需要分步变化的动画。n 表示步数,动画在整个过程中将分成 n 个步骤,通常用于精灵图或帧动画。start:让每个步骤在开始时立即切换到下一个帧或状态。end:默认值,控制动画的切换时机,使得每个步骤的变化会在当前步骤的结束时才切换到下一个状态。
    • cubic-bezier(p1, p2, p3, p4):自定义贝塞尔曲线,可以精确控制动画的速度变化。通过四个控制点来定义曲线的形状。
    • snap:这个选项适用于快速而准确地切换动画,就像点击了“快进”按钮一样,允许动画快速跳跃至目标位置。snap 是 CSS 动画中的一个新的时间函数,主要用于在动画开始或结束时直接跳转。
    • inherit:继承父元素的 timing-function 属性值。
    • initial:设置为属性的初始值,即 ease。
    • unset:设置为属性的默认值或者继承值。对于 animation,这通常表现为继承父元素的值或其默认值。
  • delay:动画开始前的延迟时间,单位为秒(s)或毫秒(ms)。
  • iteration-count:动画的播放次数,infinite 表示无限次循环,数字表示播放的具体次数。
  • direction:控制动画播放方向,常用值有:normal(正常播放)、reverse(反向播放)、alternate(交替播放)、alternate-reverse(交替反向播放)。    
  • fill-mode:设置动画结束后的状态,常用值有:forwards(保持动画结束时的样式)、backwards(保持动画开始时的样式)、both(前后都保持)。
  • animation-play-state:暂停动画。
    • running:(默认值)播放动画
    • paused:暂停动画

案例

animation参数说明 代码示例

<style>
    .container {
        width: 300px;
        height: 100px;
        border: 2px dashed gray;
    }

    @keyframes moveRight {
        0% {
            transform: translateX(0);
        }

        100% {
            transform: translateX(200px);
        }
    }

    .box {
        width: 100px;
        height: 100px;
        background: lightblue;
        /* 动画名:moveRight。持续时间:2s。缓动函数:linear,匀速。延迟:0s,立即开始。播放次数:1,只播放一次。播放方向:normal,从头到尾播放。填充模式:forwards,动画结束后停留在结束状态。 */
        animation: moveRight 2s linear 0s 1 normal forwards;
    }
</style>
<div class="container">
    <div class="box"></div>
</div>

效果图


颜色渐变和暂停动画 代码示例

<style>
    @keyframes colorChange {
        0% {
            background-color: red;
        }

        25% {
            background-color: antiquewhite;
        }

        50% {
            background-color: blue;
        }

        75% {
            background-color: chartreuse;
        }

        100% {
            background-color: green;
        }
    }

    .box {
        animation: colorChange 5s linear infinite;
        width: 100px;
        height: 100px;
    }
    
    /* 暂停动画 */
    .box:hover {
        animation-play-state: paused;
    }
</style>

<div class="box"></div>

效果图


iteration-count: infinite 无限循环动画 代码示例

<style>
    @keyframes spin {
        0% {
            transform: rotate(0deg);
        }

        100% {
            transform: rotate(360deg);
        }
    }

    .box {
        /* @keyframes动画名称,动画持续时间 2s, linear: 均速动画,延迟0s, infinite:无限循环*/
        animation: spin 2s linear 0s infinite;
        width: 100px;
        height: 100px;
        background: skyblue;
        margin: 50px;
    }
</style>

<div class="box"></div>

效果图


抖动效果动画 代码示例

<style>
    @keyframes bounce {
        0% {
            transform: translateY(0);
        }

        50% {
            transform: translateY(-50px);
        }

        100% {
            transform: translateY(0);
        }
    }

    .box {
        /* 速度短些,就抖动很快 animation: bounce 0.3s ease-in-out 0s infinite; */
        animation: bounce 1s ease-in-out 0s infinite;
        width: 100px;
        height: 100px;
        background: skyblue;
        margin: 100px;
    }
</style>

<div class="box"></div>

效果图


timing-function: step-start 文字闪烁动画 代码示例

<style>
    @keyframes blink {

        0%,
        100% {
            opacity: 1;
            color: crimson;
        }

        51% {
            opacity: 0;
        }
    }

    p {
        animation: blink 1s step-start infinite;
        font-size: 20px;
        font-weight: bold;
    }
</style>

<p>文字闪烁</p>

效果图


JavaScript 动态控制 @keyframes 动画

document.querySelector('.box').style.animation = 'fadeIn 2s ease-in-out';

边框闪烁动画

<style>
    @keyframes borderFlash {
        0% {
            border-color: red;
        }

        100% {
            border-color: blue;
        }
    }

    button {
        width: 150px;
        height: 30px;
        border: 2px solid red;
        border-radius: 5px;
        /* 初始边框颜色为红色 */
        animation: borderFlash 1s infinite alternate;
        /* 应用动画 */
    }
</style>

<button>确定</button>

效果图


文本阴影闪烁动画

<style>
    @keyframes textGlow {
        0% {
            text-shadow: 0 0 10px red;
        }

        100% {
            text-shadow: 0 0 15px blue;
        }
    }

    .text {
        font-size: 20px;
        animation: textGlow 1s infinite alternate;
    }
</style>
<p class="text">确认</p>

效果图


理解 steps 属性、单行

用例图(精灵图),每格是 100px, 100px

例如:steps(5),表示把@keyframes动画的 from(0%) 到 to(100%) 分成了5 帧(走5步)

代码如下:

<style>
    .box {
        width: 100px;
        height: 100px;
        background-image: url(abcde.png);
        animation: sprite 5s steps(5) infinite;
    }

    @keyframes sprite {
        from {
            background-position: 0px 0px;
        }

        to {
            /* 注意,这里 -500 是 第五张图的结尾,不是开头(开头是-400px, 那样结果不是你想要的) */
            background-position: -500px 0px;
        }
    }
</style>

<div class="box"></div>

效果图


理解 steps 属性、多行换行

用例图(多行精灵图),每格是 100px, 100px

例如:多行精灵图,怎么换行?

代码如下:

注意:

  • 代码第一行是 0% - 50%,正常来说第二行应该是 51%开头。实际正确写法应该是 50.0001%。因为51%有明显的从第一行切换到第二行的换行动画,这不是我们想要的。
  • 我们有 2行5列共10 个图片的一张精灵图,正常来说应该是 steps(10) ,10帧动画。 实际正确写法应该是 steps(5),表示了 steps 是作用在一行上的函数,并不是整个精灵图的所有行。
<style>
    .box {
        width: 100px;
        height: 100px;
        background-repeat: no-repeat;
        background-image: url(abcdefghij.png);
        animation: sprite 5s steps(5) infinite;
    }

    @keyframes sprite {

        /* 第一行 开始 */
        0% {
            background-position: 0px 0px;
        }

        /* 第一行 结束 */
        50% {
            background-position: -500px 0px;
        }

        /* 第二行 开始,要写 50.01 50.001,带234为不等的小数,不能写成 51,那样有明显的换行效果暴露出来 */
        50.001% {
            background-position: 0px -100px;
        }

        /* 第二行 结束 */
        100% {
            background-position: -500px -100px;
        }
    }
</style>

<div class="box"></div>

。           


理解 step-end 属性、单行

用例图(精灵图),每格的位置不确定

例如:显示 a、b、c、d、e 五张图片,css中的精灵图像是一圈循环,如果你想拿到 5个数,你需要切 6 刀,例如:c d e a b... 这样不停的循环。即:关键帧的数量=图片数量+1

代码如下:

<style>
    .box {
        width: 125px;
        height: 125px;
        background-image: url(sprites.jpg);
        animation: sprite 5s step-end infinite;
    }

    @keyframes sprite {
        0% {
            /* 第一张图片 */
            background-position: 8px -6px;
        }

        20% {
            /* 第二张图片 */
            background-position: -112px -6px;
        }

        40% {
            /* 第三张图片 */
            background-position: -224px -6px;
        }

        60% {
            /* 第四张图片 */
            background-position: -352px -6px;
        }

        80% {
            /* 第五张图片 */
            background-position: -466px -6px;
        }

        100% {
            /* 循环回到第一张图片, 内容写什么不重要,重要的是要有这个第 6 帧 */
            background-position: -587px -6px;
        }
    }
</style>

<div class="box"></div>

注意:这里不能使用 steps(n),那就是把 0% 分成 n 帧(走n步),20% 分成 n 帧(走n步),以此类推。step-start 和 step-end 类似,step-end 从第一张图开始,step-start 从第二张图开始

效果图


理解 step-end 属性、多行换行

例如:显示 a、b、c、d、e、f、g、h、i、j、k 十张图片,中间有换行。记住不管有几个图片,关键帧是图片数量+1

代码如下:

<style>
    .box {
        width: 125px;
        height: 125px;
        background-image: url(sprites.jpg);
        animation: sprite 8s step-end infinite;
    }

    @keyframes sprite {
        0% {
            /* A 第一张图片 */
            background-position: 8px -6px;
        }

        9.09% {
            /* B 第二张图片 */
            background-position: -112px -6px;
        }

        18.18% {
            /* C 第三张图片 */
            background-position: -224px -6px;
        }

        27.27% {
            /* D 第四张图片 */
            background-position: -352px -6px;
        }

        36.36% {
            /* E 第五张图片 */
            background-position: -466px -6px;
        }

        /* 第二行 */
        45.45% {
            /* F */
            background-position: 0px -135px;
            width: 95px;
        }

        54.55% {
            /* G */
            background-position: -93px -135px;
            width: 125px;
        }

        63.64% {
            /* H */
            background-position: -208px -135px;
            width: 116px;
        }

        72.73% {
            /* I */
            background-position: -324px -135px;
            width: 64px;
        }

        81.82% {
            /* J */
            background-position: -389px -135px;
            width: 104;
        }

        90.91% {
            /* K */
            background-position: -494px -135px;
            width: 106px;
        }

        /* 循环回到第一张图片,11个图片需要12个点,最后一个点,内容是什么不容要,重要的是一定要有这个点 */
        100% {}
    }
</style>

<div class="box"></div>

效果图


植物大战僵尸

用例图(僵尸精灵图)

代码示例:

<style>
    .box {
        width: 1400px;
        height: 600px;
        background-image: url(img/bg.png);
        /* 超出div的部分隐藏 */
        overflow: hidden;
        display: flex;
        /* 显示在右下角 */
        justify-content: flex-end;
        align-items: flex-end;
        /* 垂直布局 */
        flex-direction: column;
    }

    .box div {
        position: relative;
        width: 155px;
        height: 115px;
        background-repeat: no-repeat;
        /* 默认出现的位置(默认在背景图外面) */
        background-position: 155px -64px;
        /* 僵尸精灵图 */
        background-image: url(img/js.png);
    }

    .sprite_1 {
        margin-bottom: 70px;
        /* 让精灵连续行走并向前移动 */
        animation: walk-cycle 1500ms step-end 10s infinite, move-forward 50s linear 10s 1 normal forwards;
    }

    .sprite_2 {
        margin-bottom: 55px;
        /* 让精灵连续行走并向前移动 */
        animation: walk-cycle 4s step-end infinite, move-forward 105s linear 1 normal forwards;
    }

    /* 角色行走动画(切换精灵图的帧) */
    @keyframes walk-cycle {
        0% {
            /* 1 */
            background-position: -4px -64px;
        }

        1.25% {
            /* 2 */
            background-position: -163px -64px;
        }

        2.5% {
            /* 3 */
            background-position: -322px -64px;
        }

        3.75% {
            /* 4 */
            background-position: -481px -64px;
        }

        5% {
            /* 5 */
            background-position: -640px -64px;
        }

        6.25% {
            /* 6 */
            background-position: -799px -64px;
        }

        7.5% {
            /* 7 */
            background-position: -958px -64px;
        }

        8.75% {
            /* 8 */
            background-position: -1117px -64px;
        }

        10% {
            /* 9 */
            background-position: -1276px -64px;
        }

        11.25% {
            /* 10 */
            background-position: -1435px -64px;
        }

        12.5% {
            /* 11 */
            background-position: -1594px -64px;
        }

        13.75% {
            /* 12 */
            background-position: -1753px -64px;
        }

        /* 第二行 */
        15% {
            /* 1 */
            background-position: -4px -183px;
        }

        16.25% {
            background-position: -163px -183px;
        }

        17.5% {
            background-position: -322px -183px;
        }

        18.75% {
            background-position: -481px -183px;
        }

        20% {
            background-position: -640px -183px;
        }

        21.25% {
            background-position: -799px -183px;
        }

        22.5% {
            background-position: -958px -183px;
        }

        23.75% {
            background-position: -1117px -183px;
        }

        25% {
            background-position: -1276px -183px;
        }

        26.25% {
            background-position: -1435px -183px;
        }

        27.5% {
            background-position: -1594px -183px;
        }

        28.75% {
            background-position: -1753px -183px;
        }

        /* 第三行 */
        30% {
            background-position: -4px -302px;
        }

        31.25% {
            background-position: -163px -302px;
        }

        32.5% {
            background-position: -322px -302px;
        }

        33.75% {
            background-position: -481px -302px;
        }

        35% {
            background-position: -640px -302px;
        }

        36.25% {
            background-position: -799px -302px;
        }

        37.5% {
            background-position: -958px -302px;
        }

        38.75% {
            background-position: -1117px -302px;
        }

        40% {
            background-position: -1276px -302px;
        }

        41.25% {
            background-position: -1435px -302px;
        }

        42.5% {
            background-position: -1594px -302px;
        }

        43.75% {
            background-position: -1753px -302px;
        }

        /* 第 4 行 */
        45% {
            background-position: -4px -421px;
        }

        46.25% {
            background-position: -163px -421px;
        }

        47.5% {
            background-position: -322px -421px;
        }

        48.75% {
            background-position: -481px -421px;
        }

        50% {
            background-position: -640px -421px;
        }

        51.25% {
            background-position: -799px -421px;
        }

        52.5% {
            background-position: -958px -421px;
        }

        53.75% {
            background-position: -1117px -421px;
        }

        55% {
            background-position: -1276px -421px;
        }

        56.25% {
            background-position: -1435px -421px;
        }

        57.5% {
            background-position: -1594px -421px;
        }

        58.75% {
            background-position: -1753px -421px;
        }

        /* 第 5 行 */
        60% {
            background-position: -4px -540px;
        }

        61.25% {
            background-position: -163px -540px;
        }

        62.5% {
            background-position: -322px -540px;
        }

        63.75% {
            background-position: -481px -540px;
        }

        65% {
            background-position: -640px -540px;
        }

        66.25% {
            background-position: -799px -540px;
        }

        67.5% {
            background-position: -958px -540px;
        }

        68.75% {
            background-position: -1117px -540px;
        }

        70% {
            background-position: -1276px -540px;
        }

        71.25% {
            background-position: -1435px -540px;
        }

        72.5% {
            background-position: -1594px -540px;
        }

        73.75% {
            background-position: -1753px -540px;
        }

        /* 第 6 行 */
        75% {
            background-position: -4px -659px;
        }

        76.25% {
            background-position: -163px -659px;
        }

        77.5% {
            background-position: -322px -659px;
        }

        78.75% {
            background-position: -481px -659px;
        }

        80% {
            background-position: -640px -659px;
        }

        81.25% {
            background-position: -799px -659px;
        }

        82.5% {
            background-position: -958px -659px;
        }

        83.75% {
            background-position: -1117px -659px;
        }

        85% {
            background-position: -1276px -659px;
        }

        86.25% {
            background-position: -1435px -659px;
        }

        87.5% {
            background-position: -1594px -659px;
        }

        88.75% {
            background-position: -1753px -659px;
        }

        /* 第 7 行 */
        90% {
            background-position: -4px -778px;
        }

        91.25% {
            background-position: -163px -778px;
        }

        92.5% {
            background-position: -322px -778px;
        }

        93.75% {
            background-position: -481px -778px;
        }

        95% {
            background-position: -640px -778px;
        }

        96.25% {
            background-position: -799px -778px;
        }

        97.5% {
            background-position: -958px -778px;
        }

        98.75% {
            background-position: -1117px -778px;
        }

        100% {}
    }

    /* 角色前进动画(左右移动) */
    @keyframes move-forward {

        /* 移动到屏幕左侧 */
        from {
            /* 使用 position 非 static 让 left 生效 */
            left: 155px;
        }

        to {
            left: -1400px;
        }
    }
</style>

<div class="box">
    <div class="sprite_1"></div>
    <div class="sprite_2"></div>
</div>

效果图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

7 号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值