结束与起始之界

✈️ 多多航空降落中……

🎸 K.K. 在调吉他弦……

🍊 摇树时躲开黄蜂……

📝 moudicat2018 年 03 月 04 日更新于 2026-05-275 次阅读

[译文]跟着NEET学CSS动画 第一课

[译文]跟着NEET学CSS动画 第一课

💡 翻译自@yuki540

版权声明

原文地址: http://www.magical-girl.site/entry/2018/02/25/ニートに学ぶCSS_Animation演出講座_1時間目

作者: yuki540

Twitter: https://twitter.com/eriri_jp

Github: https://github.com/yuki540net

译者?注: 其实我日语仅停留在五十音水平,所以肯定会有翻译错的地方,大部分都是主观翻译。

欢迎大佬在评论区指正! 谢谢!

顺便可以去看看博主的网站 (设计很赞使用了很多SVG、CSS动画,视觉感受一级棒. ps.国内可能会有些慢)

你好

logo

本来是以“跟着Mirai Akari”为系列文章标题的,但是怕被打所以算了吧 ⬇

mirai akari

我觉得听NEET讲课应该是挺没意思的,所以请把我当做美少女吧 xd

好,再来一次!

你好, 我是yuki540!

在这一系列中,我会逐一解释分析我之前做过的CSS动画的原理。

我所做的东西很简单,都能通过基本的CSS知识完成,所以我觉得大家只要很短时间就能理解。

这节课中,我们只使用HTML和CSS,那么,快点开始吧!

这次的动画

animation gif

⬆ 这次我会分析这种我经常使用的"幻灯片"动画

这就是我的项目共依存中使用的,这是一个简单且可以多处复用的动画,所以可以把它放在你的项目中试试 :)

首先,如果你想看看最终的效果,链接在这里。(注: 国内图片加载速度比较慢,等图片加载之后再刷新即可)

好的,如果你看完了,那。。编辑器启动! 一起来敲代码吧。

HTML结构

首先从HTML开始。

<main id="root">
  <div id="screen">
    <section class="images">
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
    </section>
    <section class="paint"></section>
  </div>
</main>

看起来还是比较简单,大致结构是这样:

#screen 是幻灯片的容器

.images 是图片列表元素

.paint 是最初覆盖整个幻灯片的元素

样式

HTML写完了,接下来就写样式吧。

首先是#root#screen

html, body {
  margin: 0;
  padding: 0;
}
#root {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  min-width: 1100px; min-height: 650px;
  background-color: #eee;
}
 
#screen {
  position: absolute;
  left: calc(50% - 330px);
  top: calc(50% - 235px);
  width: 650px; height: 450px;
  background-color: #fff;
  border: solid 10px #fff;
  box-shadow: 0 0 20px #444;
  overflow: hidden;
}

#root铺满整个屏幕,并把#screen垂直水平居中。

对于那些不想使用calc的人可以使用left: 50%; margin-left: -330px也是可以的。

接下来是图片列表的style

.images {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
}
 
.images .image {
  position: absolute;
  top: 0; left: 0;
  width: 0%; height: 100%;
  overflow: hidden;
}
.images .image:after {
  content: "";
  display: block;
  position: absolute;
  top: 0; left: 0;
  width: 650px; height: 450px;
  background-size: cover;
  background-position: center;
}
.images .image:nth-child(1):after { background-image: url(./images/1.png); }
.images .image:nth-child(2):after { background-image: url(./images/2.png); }
.images .image:nth-child(3):after { background-image: url(./images/3.png); }
.images .image:nth-child(4):after { background-image: url(./images/4.png); }

选4张你喜欢的图放进去吧!

.images本身只与#screen的大小相匹配,但我希望您注意这三点:

  • .image的宽度为0%
  • .image有overflow: hidden
  • .image:after确保大小是由px而不是%确定的

在这个效果中,为了改变宽度,同时保持图像的形状,.image的子元素的宽必须要是固定的。

如果使用%的话,伪元素就会去尝试匹配父元素的宽,当父元素发生变化的时候,伪元素(.image:after)的图像就会发生移动,大概就是这样。

使用%

use %

使用px

use px

指定px之后,如果子元素大于父元素,那就需要overflow: hidden属性,将显示在外部图像的裁剪掉。

下一个是.paint的style

.paint {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  background-color: #444;
}

搞定。.paint最初只覆盖整个页面。

动画

大家知道@keyframes {}animation的使用方法吗?

我觉得很多人都应该知道吧,那么我就来简单的说明一下。

对于css动画,在简单运动(悬停时颜色发生变化等)的情况下,通常使用transition属性。但像我的主页这样的长动画就无能为力了。

于是乎animation属性登场啦。

animation属性如下:

.demo {
  animation: fadeout 0.5s ease 0s forwards;
}
 
@keyframes fadeout {
  0% { opacity: 1; }
  100% { opacity: 0; }
}

这是一个淡出动画,其中元素逐渐变为透明,并在动画结束后保持透明,耗时0.5s。

animation属性的每个参数如下

animation:[关键帧名称] [动画时间] [动画缓动曲线] [动画开始时间] [动画时间之外的状态]

它还有很多其他的属性值,不过这些就够用了。

接下来就是很重要的@keyframes {}了。

它是通过指定介于0% ~ 100%之间的属性来创建动画。(0%、100% 可以分别表示为from、to)。

如果你了解关键帧的话,那么理解这个就并不困难,复杂的动画就可以通过关键帧来控制。

如果你不熟悉这一点...请参考这个

.paint的动画

是的。之前我们将.paint覆盖了整个区域,现在我们写一个动画将它移开。

@keyframes fadeout_paint {
  0% { /* 初始状态 */
    transform: translate(0, 0) scale(1);
    width: 100%; height: 100%;
    border-radius: 0;
  }
  30% { /* 变为小球的形状 */
    transform: translate(305px, 205px) scale(1);
    width: 40px; height: 40px;
    border-radius: 50%;
  }
  50% {
    transform: translate(305px, 205px) scale(1.3);
    width: 40px; height: 40px;
    border-radius: 50%;
  }
  70% { /* 弹跳的效果 */
    transform: translate(305px, 205px) scale(1);
    width: 40px; height: 40px;
    border-radius: 50%;
  }
  100% { /* 跑到屏幕的左侧 */
    transform: translate(-40px, 205px) scale(1);
    width: 40px; height: 40px;
    border-radius: 50%;
  }
}

这还是比较复杂的,来看一下:

  • 在0%和30%之间,变成一个圆形。

  • 在30%到70%之间,让小球稍稍变大,有一种弹力的效果

  • 在70%和100%之间,将小球移动到左侧

接下来,给.paint写动画。

.paint { animation: fadeout_paint 1s ease 0.5s forwards; }

这个动画表示的是,在0.5秒后开始执行1秒的fadeout_paint动画,同时在之后保持最后一个关键帧的状态。

.image的动画

.image就比较简单。让width从0%到100%变化即可。

@keyframes show_image {
  0%   { width: 0%; }
  100% { width: 100%; }
}

每个.image的动画如下:

/*** 幻灯片动画 ***/
.images .image:nth-child(1) { animation: show_image 0.6s ease 1.5s forwards; }
.images .image:nth-child(2) { animation: show_image 0.6s ease 1.7s forwards; }
.images .image:nth-child(3) { animation: show_image 0.6s ease 1.9s forwards; }
.images .image:nth-child(4) { animation: show_image 0.6s ease 2.1s forwards; }

.paint动画完成后,让每个图片以间隔0.2s的时间差开始动画。

是的,就是这样!

请刷新浏览器看看。

完成了,你真是个天才!

至此,所有的代码都在这里

结束语

如果有"不明白"或是“我想要这个的解释!”的话,可以用Twitter和我联系。

调整关键帧是可以具有独创性的,所以请自己尝试修改一些参数和属性。

我希望能帮助你对CSS动画产生更多新的看法。

之后会每周日更新的,那再会了~

じゃーねー

捡到了漂流瓶!

根据《非经营性互联网信息服务备案管理办法》,小岛暂不开放公开留言 / 评论。

想和我聊聊的话,欢迎通过其他渠道找我~