描述@keyframes规则在 CSS 动画中的原理及作用,如何创建一个简单的动画

大白话描述@keyframes规则在 CSS 动画中的原理及作用,如何创建一个简单的动画?

嘿,朋友!咱来聊聊 CSS 里超酷的 @keyframes 规则。这玩意儿就像是动画的剧本,能让网页元素动起来,就像给它们施了魔法一样!

原理和作用

想象一下,你在拍一部动画电影。@keyframes 就像是这部电影的分镜脚本,它规定了元素在动画过程中不同时间点的样子。你可以设定元素在 0%(也就是动画开始的时候)、50%(动画进行到一半)、100%(动画结束)等不同阶段的样式,比如位置、大小、颜色啥的。浏览器就会根据这个脚本,平滑地把元素从一个状态变到另一个状态,这样就有了动画效果。

创建简单动画步骤

咱来创建一个简单的动画,让一个方块从左到右移动。

1. 定义 @keyframes 规则

首先,你得写好这个"动画剧本"。给这个剧本取个名字,这里我们叫它 moveRight

css 复制代码
/* 定义一个名为 moveRight 的动画剧本 */
@keyframes moveRight {
    /* 动画开始时,方块的左边距是 0px */
    from {
        margin-left: 0px;
    }
    /* 动画结束时,方块的左边距是 200px,也就是向右移动了 200px */
    to {
        margin-left: 200px;
    }
}

这里的 from 就相当于 0% 的时间点,to 相当于 100% 的时间点。你也可以用百分比来更精确地控制中间状态,比如:

css 复制代码
/* 定义一个名为 moveRight 的动画剧本 */
@keyframes moveRight {
    /* 动画开始时,方块的左边距是 0px */
    0% {
        margin-left: 0px;
    }
    /* 动画进行到 50% 时,方块的左边距是 100px */
    50% {
        margin-left: 100px;
    }
    /* 动画结束时,方块的左边距是 200px,也就是向右移动了 200px */
    100% {
        margin-left: 200px;
    }
}
2. 选择要应用动画的元素

接下来,你得找个元素来表演这个动画。这里我们用一个 <div> 元素。

html 复制代码
<!-- 创建一个 div 元素,用来展示动画 -->
<div class="animated-box"></div>
3. 给元素应用动画

最后,把这个"动画剧本"应用到元素上。

css 复制代码
/* 选择类名为 animated-box 的元素 */
.animated-box {
    /* 设置元素的宽度为 50px */
    width: 50px;
    /* 设置元素的高度为 50px */
    height: 50px;
    /* 设置元素的背景颜色为蓝色 */
    background-color: blue;
    /* 应用名为 moveRight 的动画 */
    animation-name: moveRight;
    /* 设置动画的持续时间为 3 秒 */
    animation-duration: 3s;
}

完整代码示例

把上面的代码组合起来,就是一个完整的示例:

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple CSS Animation</title>
    <style>
        /* 定义一个名为 moveRight 的动画剧本 */
        @keyframes moveRight {
            /* 动画开始时,方块的左边距是 0px */
            from {
                margin-left: 0px;
            }
            /* 动画结束时,方块的左边距是 200px,也就是向右移动了 200px */
            to {
                margin-left: 200px;
            }
        }

        /* 选择类名为 animated-box 的元素 */
        .animated-box {
            /* 设置元素的宽度为 50px */
            width: 50px;
            /* 设置元素的高度为 50px */
            height: 50px;
            /* 设置元素的背景颜色为蓝色 */
            background-color: blue;
            /* 应用名为 moveRight 的动画 */
            animation-name: moveRight;
            /* 设置动画的持续时间为 3 秒 */
            animation-duration: 3s;
        }
    </style>
</head>

<body>
    <!-- 创建一个 div 元素,用来展示动画 -->
    <div class="animated-box"></div>
</body>

</html>

把这段代码保存为一个 .html 文件,用浏览器打开,你就能看到一个蓝色的方块从左到右移动啦!是不是很有趣?现在你也可以发挥自己的创意,修改 @keyframes 规则,让元素做出更多酷炫的动画效果。

那么,除了@keyframe,还有哪些创建动画的方法?

在 CSS 里,除了 @keyframes 规则,还有其他创建动画的方法,下面为你详细介绍:

1. transition(过渡)

transition 是一种简单的动画效果创建方式,它主要用于在元素的某个属性发生变化时,让这种变化以平滑过渡的形式呈现出来,而不是瞬间改变。

原理和作用

当元素的某个 CSS 属性(如颜色、大小、位置等)的值发生改变时,transition 会让这个属性值在指定的时间内逐渐变化,从而产生动画效果。这就像是一个元素从一种状态"过渡"到另一种状态。

示例代码
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Transition Example</title>
    <style>
        /* 定义一个类名为 box 的元素样式 */
        .box {
            width: 100px;
            height: 100px;
            background-color: red;
            /* 设置过渡效果,当宽度属性改变时,在 2 秒内平滑过渡 */
            transition: width 2s;
        }

        /* 当鼠标悬停在 box 元素上时,宽度变为 300px */
        .box:hover {
            width: 300px;
        }
    </style>
</head>

<body>
    <!-- 创建一个 div 元素,应用 box 类 -->
    <div class="box"></div>
</body>

</html>

在这个例子中,当鼠标悬停在方块上时,方块的宽度会在 2 秒内从 100px 平滑地过渡到 300px。

2. transform(变换)结合 JavaScript

transform 可以对元素进行旋转、缩放、移动、倾斜等操作,而结合 JavaScript 可以动态地改变 transform 的值,从而创建动画效果。

原理和作用

transform 提供了对元素进行几何变换的能力,JavaScript 则可以控制这些变换在不同时间点的变化,实现更复杂的动画逻辑。

示例代码
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript and CSS Transform Animation</title>
    <style>
        /* 定义一个类名为 circle 的元素样式 */
        .circle {
            width: 50px;
            height: 50px;
            background-color: green;
            border-radius: 50%;
            position: absolute;
            top: 50px;
            left: 50px;
        }
    </style>
</head>

<body>
    <!-- 创建一个 div 元素,应用 circle 类 -->
    <div class="circle" id="circle"></div>
    <script>
        // 获取 circle 元素
        const circle = document.getElementById('circle');
        let angle = 0;
        // 定义一个函数,用于旋转元素
        function rotateCircle() {
            angle += 1;
            // 设置元素的 transform 属性,实现旋转效果
            circle.style.transform = `rotate(${angle}deg)`;
            // 每 10 毫秒调用一次 rotateCircle 函数,实现连续旋转
            requestAnimationFrame(rotateCircle);
        }
        // 开始旋转动画
        rotateCircle();
    </script>
</body>

</html>

在这个例子中,JavaScript 不断改变 circle 元素的旋转角度,从而让圆形元素持续旋转。

3. SVG 动画

SVG(可缩放矢量图形)本身就支持动画,通过 <animate><animateTransform> 等元素可以直接在 SVG 中创建动画。

原理和作用

SVG 动画元素可以定义在 SVG 图形的特定属性上,控制这些属性随时间的变化,从而实现动画效果。

示例代码
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SVG Animation Example</title>
</head>

<body>
    <!-- 创建一个 SVG 元素 -->
    <svg width="200" height="200" viewBox="0 0 200 200">
        <!-- 创建一个圆形元素 -->
        <circle cx="50" cy="50" r="20" fill="blue">
            <!-- 定义一个动画,让圆形的 cx 属性在 5 秒内从 50 变化到 150 -->
            <animate attributeName="cx" from="50" to="150" dur="5s" repeatCount="indefinite" />
        </circle>
    </svg>
</body>

</html>

在这个例子中,SVG 中的 <animate> 元素让圆形的 cx(圆心的 x 坐标)属性在 5 秒内从 50 变化到 150,并且无限重复这个动画。

除了transition,还有哪些创建动画的方法?

除了 transition,在前端开发中有多种创建动画的方法,以下为你详细介绍:

CSS 层面

1. @keyframes 规则

这是 CSS 中创建复杂动画的强大工具。它允许你定义动画的关键帧,也就是元素在动画过程中不同时间点的样式,浏览器会自动补全这些关键帧之间的过渡效果。

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Keyframes Animation</title>
    <style>
        /* 定义名为 bounce 的动画关键帧 */
        @keyframes bounce {
            0%, 20%, 50%, 80%, 100% {
                transform: translateY(0);
            }
            40% {
                transform: translateY(-30px);
            }
            60% {
                transform: translateY(-15px);
            }
        }

        /* 应用动画的元素样式 */
        .ball {
            width: 50px;
            height: 50px;
            background-color: red;
            border-radius: 50%;
            /* 应用 bounce 动画,持续 2 秒,无限循环 */
            animation: bounce 2s infinite;
        }
    </style>
</head>

<body>
    <!-- 创建一个应用动画的元素 -->
    <div class="ball"></div>
</body>

</html>

在上述代码中,@keyframes 定义了一个名为 bounce 的动画,模拟了小球弹跳的效果。.ball 类的元素应用了这个动画,让小球不断弹跳。

2. transform 结合 will-change

transform 可以对元素进行旋转、缩放、移动、倾斜等操作,而 will-change 可以提前告知浏览器某个元素即将发生变化,从而让浏览器提前做好优化准备,提升动画的性能。

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Transform with Will-Change</title>
    <style>
        /* 应用动画的元素样式 */
        .box {
            width: 100px;
            height: 100px;
            background-color: blue;
            /* 告知浏览器元素的 transform 属性即将发生变化 */
            will-change: transform;
            transition: transform 1s;
        }

        /* 鼠标悬停时的样式 */
        .box:hover {
            transform: rotate(45deg);
        }
    </style>
</head>

<body>
    <!-- 创建一个应用动画的元素 -->
    <div class="box"></div>
</body>

</html>

这里,will-change 让浏览器提前优化 transform 动画,当鼠标悬停在元素上时,元素会平滑地旋转 45 度。

JavaScript 层面

1. requestAnimationFrame

这是 JavaScript 中用于创建高性能动画的方法。它会在浏览器的下一次重绘之前执行传入的回调函数,从而实现流畅的动画效果。

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Request Animation Frame</title>
    <style>
        /* 应用动画的元素样式 */
        .square {
            width: 50px;
            height: 50px;
            background-color: green;
            position: absolute;
            left: 0;
        }
    </style>
</head>

<body>
    <!-- 创建一个应用动画的元素 -->
    <div class="square" id="square"></div>
    <script>
        const square = document.getElementById('square');
        let position = 0;
        // 定义动画函数
        function animate() {
            position++;
            square.style.left = position + 'px';
            // 继续调用动画函数,实现连续动画
            requestAnimationFrame(animate);
        }
        // 开始动画
        animate();
    </script>
</body>

</html>

此代码中,requestAnimationFrame 不断调用 animate 函数,让方块不断向右移动。

2. GSAP(GreenSock Animation Platform)

GSAP 是一个强大的 JavaScript 动画库,提供了丰富的动画功能和简洁的 API,能创建复杂的动画效果。

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>GSAP Animation</title>
    <!-- 引入 GSAP 库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
</head>

<body>
    <!-- 创建一个应用动画的元素 -->
    <div class="element" id="element">Animated Element</div>
    <script>
        const element = document.getElementById('element');
        // 使用 GSAP 创建动画,让元素在 2 秒内向右移动 200px 并旋转 360 度
        gsap.to(element, {
            duration: 2,
            x: 200,
            rotation: 360
        });
    </script>
</body>

</html>

在这个例子中,GSAP 的 gsap.to 方法让元素在 2 秒内向右移动 200px 并旋转 360 度。

SVG 层面

1. SVG <animate> 元素

SVG 提供了 <animate> 元素用于创建动画,它可以控制 SVG 元素的属性随时间变化。

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SVG Animate</title>
</head>

<body>
    <!-- 创建一个 SVG 元素 -->
    <svg width="200" height="200" viewBox="0 0 200 200">
        <!-- 创建一个矩形元素 -->
        <rect x="50" y="50" width="50" height="50" fill="orange">
            <!-- 定义一个动画,让矩形的 x 属性在 3 秒内从 50 变化到 150 -->
            <animate attributeName="x" from="50" to="150" dur="3s" repeatCount="indefinite" />
        </rect>
    </svg>
</body>

</html>

这里,<animate> 元素让矩形的 x 属性在 3 秒内从 50 变化到 150,并且无限循环这个动画。

除了transition,还有哪些创建动画的方法?

transition@keyframes 规则都是 CSS 中用于创建动画效果的工具,但它们在多个方面存在明显区别,下面为你详细介绍:

基本概念

  • transition :它是一种用于在元素的两个状态之间创建平滑过渡效果的机制。当元素的某个 CSS 属性值发生变化时,transition 会让这个属性值在指定的时间内逐渐改变,而不是瞬间切换。例如,当鼠标悬停在元素上时,元素的颜色或大小发生变化,使用 transition 可以让这种变化看起来更自然。
  • @keyframes@keyframes 规则允许你定义一个动画的完整过程,通过指定元素在不同时间点(关键帧)的样式,浏览器会自动补全这些关键帧之间的过渡效果,从而创建出复杂的动画序列。你可以控制动画的开始、中间和结束状态,以及中间的多个过渡状态。

语法和使用方式

  • transition:使用时需要指定要过渡的属性、过渡的持续时间,还可以选择指定过渡的延迟时间、过渡的速度曲线等。语法如下:
css 复制代码
/* 选择要应用过渡效果的元素 */
.element {
    /* 指定要过渡的属性为 width,过渡持续时间为 2 秒,过渡速度曲线为 ease */
    transition: width 2s ease;
}

/* 当元素处于悬停状态时,改变 width 属性的值 */
.element:hover {
    width: 200px;
}

在上述代码中,当鼠标悬停在 .element 元素上时,其 width 属性会在 2 秒内平滑地从初始值过渡到 200px。

  • @keyframes :首先需要使用 @keyframes 关键字定义一个动画,为其命名并指定关键帧的样式。然后,将这个动画应用到元素上,并设置动画的持续时间、播放次数等属性。语法如下:
css 复制代码
/* 定义一个名为 slide 的动画 */
@keyframes slide {
    /* 动画开始时,元素的左边距为 0px */
    from {
        margin-left: 0px;
    }
    /* 动画结束时,元素的左边距为 200px */
    to {
        margin-left: 200px;
    }
}

/* 选择要应用动画的元素 */
.element {
    /* 应用名为 slide 的动画,动画持续时间为 3 秒,无限循环播放 */
    animation: slide 3s infinite;
}

这里,.element 元素会不断地从左边移动到右边,每次移动的过程持续 3 秒。

动画复杂度

  • transition:适用于创建简单的、从一个状态到另一个状态的过渡效果。它只能处理两个状态之间的变化,无法创建包含多个中间状态的复杂动画。例如,你只能在元素的初始状态和悬停状态之间创建过渡效果。
  • @keyframes:可以创建非常复杂的动画,因为你可以定义多个关键帧,精确控制元素在动画过程中的每一个阶段的样式。你可以实现元素的多次移动、旋转、缩放等组合效果,还可以设置不同的时间间隔和速度曲线。

触发方式

  • transition :通常需要一个事件来触发属性的变化,从而启动过渡效果。常见的触发事件包括鼠标悬停(:hover)、焦点获取(:focus)、元素的激活状态(:active)等。只有当这些事件发生时,元素的属性值发生改变,过渡效果才会开始。
  • @keyframes :动画一旦应用到元素上,就会根据设置的属性自动开始播放,不需要额外的事件触发。你可以通过设置 animation-play-state 属性来暂停或继续动画的播放。

应用场景

  • transition :常用于简单的交互效果,如按钮的悬停效果、菜单的展开和收缩等。这些场景只需要在两个状态之间进行平滑过渡,使用 transition 可以快速实现且代码简洁。
  • @keyframes :适用于创建复杂的动画效果,如加载动画、页面切换动画、角色动画等。当需要精确控制动画的每一个阶段时,@keyframes 是更好的选择。
相关推荐
Ticnix4 小时前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts
纯爱掌门人4 小时前
终焉轮回里,藏着 AI 与人类的答案
前端·人工智能·aigc
twl4 小时前
OpenClaw 深度技术解析
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Grok API 申请及使用
前端
星光不问赶路人4 小时前
vue3使用jsx语法详解
前端·vue.js
天蓝色的鱼鱼4 小时前
shadcn/ui,给你一个真正可控的UI组件库
前端
布列瑟农的星空4 小时前
前端都能看懂的Rust入门教程(三)——控制流语句
前端·后端·rust
Mr Xu_5 小时前
Vue 3 中计算属性的最佳实践:提升可读性、可维护性与性能
前端·javascript
jerrywus5 小时前
我写了个 Claude Code Skill,再也不用手动切图传 COS 了
前端·agent·claude
玖月晴空5 小时前
探索关于Spec 和Skills 的一些实战运用-Kiro篇
前端·aigc·代码规范