Skip to content

CSS 动画 第一部分:创建动画、分配动画、播放次数、方向、延迟

目录

Hello, animation!

理论

欢迎来到我们的 CSS 动画课程,这将是一次奇妙的探索!我们将走文明进化之路,征服深空。我们将在基础课程中对物体进行移动、旋转、变换。如果需要看更多的理论,请查阅 MDN 的文档;如果需要实践,我们就来看第一个任务吧!🚀

CSS 赋予你创建复杂动画的能力,你可以使用多种方式控制它们。一个 CSS 动画的描述分为两部分:一组关键帧 @keyframes 和动画参数。

下面是一个动画中简单的关键帧描述:

css
@keyframes stretching {
  0% {
    width: 100px;
  }
  100% {
    width: 200px;
  }
}

这个例子中的动画被称作 stretching,描述了一个元素从初始状态变化到最终状态。这个动画可以被应用到任何元素上。使用动画时,你只需要添加两个属性到你的 CSS 中:动画名字和动画持续时间,并且给出相应的属性值。举个例子:

css
.button {
  animation-name: stretching;
  animation-duration: 1s;
}

这段代码会将名为 stretching 的动画应用到所有拥有 button 类的元素上。这段代码的结果是,对应的元素的宽度会在 1 秒内从 100px 逐渐拉伸到 200px。

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Hello, animation!</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch1.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="ancient">
    <div class="stone">
      <div class="wood-wheel"></div>
    </div>
  </body>
</html>
css
@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.wood-wheel {
  animation-name: rotate;
  animation-duration: 2s;
}

目标

  • 动画 @keyframes rotate 的关键帧描述;
  • .wood-wheel 类的动画规则。

示例

@keyframes : 故事板

理论

对于每个动画,你需要定义它的名字,并使用 fromto 关键字或是 0%100% 的值来描述其初始状态和最终状态。

同样的,你还可以使用百分数来定义更多的中间关键帧。

如果初始帧没有定义,动画会从元素的初始状态开始播放,播放到 @keyframes 描述的最近的状态,以此类推。

如果最终帧没有定义,当到达最后一个中间状态后,动画将继续播放到元素的初始状态。

@keyframes 中的帧可以按任意顺序排列,但推荐按升序排列。

动画的持续时间,即 animation-duration 属性,接收毫秒或秒值,例如:10s100ms

下面我们来试一下创建一个动画,不提供初始值,只提供 50%100% 两个关键帧。

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>@keyframes: storyboard</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch1.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="ancient">
    <div class="stone">
        <div class="barrow-wheel"></div>
    </div>
  </body>
</html>
css
.barrow-wheel {
  animation-name: rotate;
  animation-duration: 2s;
}

@keyframes rotate {
  50% {
    transform: rotate(-90deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

目标

  • 为 50% 关键帧添加角度旋转 rotate(90deg),为 100% 关键帧添加旋转 360°

  • 将 50% 关键帧的旋转角度调整为 -90°

示例

@keyframes: fromto

理论

像上节课所讲解的那样,初始和最终的关键帧是由 fromto0%100% 的值来定义的。

中间状态的关键帧是由百分数形式的值来定义的,下面是一个包含四个帧的动画:

css
@keyframes coloring {
  from { background-color: red; }
  33%  { background-color: yellow; }
  66%  { background-color: green; }
  to   { background-color: blue; }
}

接下来我们来尝试一下 from to 和中间状态的关键帧!

目标

创建一个名为 list-up 的动画,包含如下关键帧:

  • from 初始帧是 transform: translateY(0px)
  • 50% 帧是 transform: translateY(-250px)
  • 100% 最终帧是 transform: translateY(-300px)

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>@keyframes: from and to</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch1.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="ancient">
    <div class="lift-top">
      <div class="platform">
        <span class="stone-wheel"></span>
      </div>
    </div>
  </body>
</html>
css
.platform {
  animation-name: lift-up;
  animation-duration: 3s;
}

@keyframes lift-up {
  from {
    transform: translateY(0px);
  }
  50% {
    transform: translateY(-250px);
  }
  100% {
    transform: translateY(-300px);
  }
}

示例

@keyframes: 帧分组

理论

@keyframes 中的关键帧可以成组,把关键字放到逗号分隔的字符串中即可。我们看下面的例子:

css
@keyframes stretching {
  0%, 50% {
    width: 100px;
  }
  100% {
    width: 200px;
  }
}

在这个例子中,前两个帧组成了一个组。对应的元素会在动画开始后宽度变为 100px,并且整个动画的前一半时间内都保持 100px 的宽度。然后,该元素的宽度会从 100px 变为 200px

目标

  • 50% 的帧改为 50%, 80%
  • 50%, 80% 中的动画改为 transform: translateY(-50px)

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>@keyframes: frame grouping</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch1.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="ancient">
    <div class="lift-top">
      <div class="platform">
        <span class="stone-wheel"></span>
      </div>
    </div>
  </body>
</html>
css
.platform {
  animation-name: lift-up;
  animation-duration: 3s;
}

@keyframes lift-up {
  0% {
    transform: translateY(0px);
  }
  50%, 80% {
    transform: translateY(-50px);
  }
  100% {
    transform: translateY(-300px);
  }
}

示例

复杂动画,其一

理论

更多时候,我们会将很多动画分配给同一个元素。

如果这些动画中变换了元素不同的属性,这些动画效果会同时播放。

在这一节和下一节中,我们会尝试在同一个项目中创建一个复杂的动画。首先我们创建第一个动画,并分配给页面元素。

目标

  • 创建一个叫做 rotate 的动画,在关键帧 50% 的时候做一个旋转变换 transform: rotate(360deg)

  • 将这个动画分配给 .stone-wheel,并设置持续时间 3s

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Complex animation, step 1</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch1.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="ancient">
    <div class="lift-bottom">
      <span class="stone-wheel"></span>
    </div>
  </body>
</html>
css
@keyframes rotate {
  50% {
    transform: rotate(360deg);
  }
}

.stone-wheel {
  animation-name: rotate;
  animation-duration: 3s;
}

示例

复杂动画,其二

理论

接下来我们看一下如何能为元素分配第二个同时播放的动画。

假设我们有如下两个动画:

css
@keyframes move {
  to { left: 100px; }
}
@keyframes stretch {
  to { width: 100px; }
}

要给一个元素分配第二个动画,你需要添加它们的动画名称和持续时间,使用逗号分开。

css
.element {
  animation-name: move, stretch;
  animation-duration: 5s, 5s;
}

在这个例子中,两个动画将同时开始,元素将会在 5 秒内同时移动和拉伸。

多重动画就像背景和阴影的 css 属性那样,传入多个值,用逗号分隔即可。

我们继续上一节的代码,为元素添加另一个动画吧。

目标

  • 创建一个叫做 move 的动画,包含如下关键帧:

    1. 50%bottom: 0px;
    2. 100%bottom: -50px
  • 添加第二个移动的动画,持续时间 6s,分配给 .stone-wheel 元素。

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Complex animation, step 2</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch1.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="ancient">
    <div class="lift-bottom">
      <span class="stone-wheel"></span>
    </div>
  </body>
</html>
css
@keyframes rotate {
  50% {
    transform: rotate(360deg);
  }
}

@keyframes move {
    50% {
      bottom: 0px;  
    }
    100% {
      bottom: -50px;  
    }
}


.stone-wheel {
  animation-name: rotate, move;
  animation-duration: 3s, 6s;
}

示例

水上冒险

理论

在我们学习 CSS 的过程中,我们将目睹文明的演变。现在我们将前往一个充满机械装置和齿轮的新世界。

你的任务就是创建必要的动画然后驾驶轮船驶向海外。animation-nameanimation-duration 已经定义好了。

目的

  • 创建一个动画 move-clouds,包含一个关键帧 to,进行变换 translateX(-1000px)

  • 创建一个动画 move-sun,包含关键帧 to,进行变换 translate(350px, -400px)

  • 创建一个动画 move-ship,包含关键帧 to,进行变换 translateX(1000px)

  • 让彗星也动起来。

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Water adventure</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch1.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="ancient-world">
    <div>
      <div class="comet"></div>
      <div class="sun-small"></div>
      <div class="clouds"></div>
      <div class="water"></div>
      <div class="ship"></div>
    </div>
  </body>
</html>
css
@keyframes move-clouds {
  to {
    transform: translateX(-1000px);  
  }
}

@keyframes move-sun {
    to {
      transform: translate(350px, -400px);  
    }
}

@keyframes move-ship {
  to {
    transform: translateX(1000px);  
  }  
}

.ship {
  animation-name: move-ship;
  animation-duration: 40s;
}

.clouds {
  animation-name: move-clouds;
  animation-duration: 40s;
}

.sun-small {
  animation-name: move-sun;
  animation-duration: 10s;
}

.comet {
  animation-name: move-comet;
  animation-duration: 10s;
}

@keyframes move-comet {
  100% {
    transform: translate(500px, 400px);
  }
}

示例

动画播放次数

理论

在我们之前的例子中,我们都是创建了一个只能播放一次的动画,然后元素就会恢复到它们的原始状态。我们可以通过 animation-iteration-count 属性,指定动画播放的次数。

该属性接收正整数或 0。如果是 0,该动画不会播放;其它情况下,动画会按照传入的数字播放对应的次数。

该属性还可以传入 infinite,此时该动画将会一直播放永不停止。

我们来试一下。

目标

  • 为箭头 .arrow 分配一个持续 2srotate 动画。

  • 然后将播放次数设置为 2

  • 然后让播放次数变为无限。

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Animation play count: animation-iteration-count</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch2.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="mechanical">
    <div class="clock">
      <span class="arrow"></span>
    </div>
  </body>
</html>
css
@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(90deg);
  }
  100% {
    transform: rotate(0deg);
  }
}

.arrow {
    animation-name: rotate;
    animation-duration: 2s;
    /* animation-iteration-count: 2; */
    animation-iteration-count: infinite;
}

示例

动画方向,其一

理论

除了动画的播放次数之外,我们还可以使用 animation-direction 来定义元素旋转的方向。默认情况下,动画是正常 normal 方向。

然而,你可以逆转动画方向,让动画倒着播放。换言之,动画将会从 to 开始播放,播放到 from。如果要这样做,为 animation-direction 属性设置 reverse

我们在下面的例子中对比两种动画方向。

目的

  • 为大齿轮 gear-big 设置动画 clockwise,持续时间 2s

  • 然后为小齿轮 .gear-small 设置动画 counterclockwise,持续时间 2s

  • 然后将两个齿轮的动画方向反转。

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Animation direction: animation-direction, step 1</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch2.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="mechanical">
    <div class="mechanism">
      <span class="gear-big"></span>
      <span class="gear-small"></span>
    </div>
  </body>
</html>
css
@keyframes clockwise {
  to {
    transform: rotate(180deg);
  }
}

@keyframes counterclockwise {
  to {
    transform: rotate(-180deg);
  }
}

.gear-big {
  animation-name: clockwise;
  animation-duration: 2s;
}

.gear-small {
  animation-name: counterclockwise;
  animation-duration: 2s;
}

.gear-big, .gear-small {
  animation-direction: reverse;  
}

示例

动画方向,其二

理论

animation-direction 还有另外两个值,可以在动画播放次数 animation-iteration-count 大于 1 的时候可以使用。它们定义了动画在播放时的交替方向。

如果设置为 alternate,奇数次播放正常,偶数次播放反转。

css
.element {
  animation-name: move;
  animation-duration: 1s;
  animation-iteration-count: 2;
  animation-direction: alternate;
}

在上面的例子中,move 动画将播放两次:第一次(奇数次)向前,第二次(偶数次)反过来。

如果设置为 alternate-reverse,奇数次将被反转,偶数次正常播放。

我们在下面的例子中看看这个属性是如何生效的。

目标

  • 将两个齿轮的播放次数都设置为 2

  • 设置交替方向播放,

  • 设置反向交替方向播放。

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Animation direction: animation-direction, step 2</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch2.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="mechanical">
    <div class="mechanism">
      <span class="gear-big"></span>
      <span class="gear-small"></span>
    </div>
  </body>
</html>
css
@keyframes clockwise {
  to {
    transform: rotate(180deg);
  }
}

@keyframes counterclockwise {
  to {
    transform: rotate(-180deg);
  }
}

.gear-big {
  animation-name: clockwise;
  animation-duration: 2s;
}

.gear-small {
  animation-name: counterclockwise;
  animation-duration: 2s;
}

.gear-big, .gear-small {                
  animation-iteration-count: 2;         
  animation-direction: alternate;       
  /* animation-direction: alternate; */
}                                       

示例

动画延迟,其一

理论

除了控制动画的持续时间之外,我们还可以设置在动画开始播放之前的延迟。

在这节和接下来的两节中,我们将创建两个动画,然后使用延迟功能,让它们依次运行。首先我们创建第一个动画,并分配给相应的元素。

目标

  • 创建一个 rotate 动画,包含一个 to 关键帧,动画内容是旋转 360deg

  • 然后将这个动画分配给 .arrow-small,持续时间 1s

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Animation delay: animation-delay, step 1</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch2.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="mechanical">
    <div class="alarm-clock">
      <span class="bell"></span>
      <span class="arrow-small"></span>
    </div>
  </body>
</html>
css
@keyframes rotate {
  to {
    transform: rotate(360deg);  
  }  
}

.arrow-small {
  
  animation-name: rotate;
  animation-duration: 1s;
}

示例

动画延迟,其二

理论

我们来准备第二个动画,下一步我们会为它设置一个延迟

目标

  • 创建一个动画 ding,包含如下关键帧:

    • 33%translateX(-15px)

    • 66%translateX(15px)

然后将其分配给 .bell,持续 1s

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Animation delay: animation-delay, step 2</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch2.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="mechanical">
    <div class="alarm-clock">
      <span class="bell"></span>
      <span class="arrow-small"></span>
    </div>
  </body>
</html>
css
@keyframes rotate {
  to {
    transform: rotate(360deg);
  }
}

.arrow-small {
  animation-name: rotate;
  animation-duration: 1s;
}


@keyframes ding {
  33% {
    transform: translateX(-15px);  
  }
  
  66% {
    transform: translateX(15px)
  }
}

.bell {
  animation-name: ding;
  animation-duration: 1s;
}

示例

动画延迟,其三

理论

animation-delay 用于设置动画延迟,语法与 animation-duration 相同。

举例来说,如果我们设置延迟 10s,动画不会立即开始播放,而是 10 秒之后才开始播放。

我们来完成之前的动画吧,让指针转一圈后铃才开始震动。

目标

为铃铛 .bell 设置如下动画:

  • 1s 延迟后开始播放,

  • 持续 100ms

  • 重复播放次数:10

实战

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Animation delay: animation-delay, step 3</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="epoch2.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="mechanical">
    <div class="alarm-clock">
      <span class="bell"></span>
      <span class="arrow-small"></span>
    </div>
  </body>
</html>
css
.bell {
  animation-name: ding;
  animation-duration: 1s;           
  animation-duration: 100ms;        
  animation-iteration-count: 10;    
  animation-delay: 1s;              
}

.arrow-small {
  animation-name: rotate;
  animation-duration: 1s;
}

@keyframes rotate {
  to {
    transform: rotate(360deg);
  }
}

@keyframes ding {
  33% {
    transform: translateX(-15px);
  }
  66% {
    transform: translateX(15px);
  }
}

示例

评论区
评论区空空如也
发送评论
名字
0 / 20
邮箱
0 / 100
评论内容
0 / 140
由于是非实名评论,所以不提供删除功能。如果你需要删除你发送的评论,或者是其他人的评论对你造成了困扰,请 发邮件给我 。同时评论区会使用 AI + 人工的方式进行审核,以达到合规要求。

© thebestxt.cc
辽ICP备16009524号-8
本站所有文章版权所有,转载请注明出处