如何用纯CSS实现"网易年度听歌报告"动画效果

969 阅读6分钟

前言

众所周知,那一年,网易云的年度听歌报告以其细腻的动画效果,悄悄惊艳了很多前端小伙伴们,但同时心里也一紧,这不是又给咱们出考题了嘛,所以接下来我将复刻一下网易云年度听歌报告的首页动画效果!

先放静态图一张,让大家了解一下基本结构。

image.png

Step1:html结构

首先分为三个部分,audio.j-bgm音频、div.music-btn.off音乐开关和

div.view.special主体视图,其中也分成三部分:太阳元素、动态元素(秋千、腿2、腿1、脖子、头)、段落文本元素

  • div.view.special:视图容器

    • div.sun:中间太阳元素

    • div.art:动态元素容器

      • div.swing.j-anim03.z-anim:摇摆秋千元素

        • div.leg2:摇摆的第二条腿。

          • div.jiojio:二的脚
        • div.leg1:摇摆的第一条腿

          • div.jiojio:一的脚
        • div.neck:摇摆脖子部分

        • div.head:摇摆头部分

          • div.part:头发
    • div.paras:段落内容容器

      • p.para:段落元素

        • em.s-fcRed:设置特殊样式的文本元素

代码:

  <audio id="j-bgm" src="./assets/bgm.mp3"></audio>
  <div class="music-btn off"></div>

  <div class="view special">
    <div class="sun"></div>
    <!-- 荡秋千 -->
    <div class="art">
      <div class="swing j-anim03 z-anim">
        <!-- 腿 -->
        <div class="leg2">
          <div class="jiojio"></div>
        </div>
        <!-- 腿 -->
        <div class="leg1">
          <div class="jiojio"></div>
        </div>
        <!-- 脖子 -->
        <div class="neck"></div>
        <!-- 头 -->
        <div class="head">
          <div class="part"></div>
        </div>
      </div>
    </div>
    <!-- 特殊内容 -->
    <div class="paras">
      <p class="para f-animLineUp" style="transition-delay: 0.2s;">
        <em class="s-fcRed">4月20日</em>
      </p>
      <p class="para f-animLineUp" style="transition-delay: 0.3s;">
        大概是很特别的一天
      </p>
      <p class="para f-animLineUp" style="transition-delay: 0.4s;">
        这一天里
      </p>
      <p class="para f-animLineUp" style="transition-delay: 0.5s;">
        你把蒲熠星的
        <em class="s-fcRed">《宇宙情歌》</em>
      </p>
      <p class="para f-animLineUp" style="transition-delay: 0.6s;">
        反复听了
        <em class="s-fcRed">31次</em>
      </p>
    </div>
  </div>

Step2:秋千动画

我们直接介绍秋千荡起来的动画效果,图片是这样的

image.png
  1. 外层压缩 :首先,我们通过将 .art 元素的 transform 属性设置为 scale(.5),将其尺寸缩小了一半,使得秋千外观更为紧凑。
  2. 设置秋千动画 :然后,我们定义了 .swing 元素,它是秋千的主体部分。我们设置了它的位置和尺寸,并且导入图片。重要的是,我们使用 transform-origin 属性将旋转点放在了视图之外的左上角,这样它就可以绕着这个点进行旋转。接着,我们给秋千应用了名为 ani4_qiuqian 的动画,使得它能够动起来。
  3. 设置动画效果 :最后,我们使用 @keyframes 关键字定义了动画 ani4_qiuqian。在这个动画中,我们设置了秋千从初始状态(0%)到中间状态(50%),再到最终状态(100%)的旋转角度变化。通过在不同时间点对 transform 属性进行修改,我们实现了秋千摆动的效果。整个动画持续6秒,使用了 cubic-bezier 函数定义了缓动效果,使得秋千的运动更加自然流畅,设置infinite让动画无限循环播放。
/* 秋千 外层压缩 */
.art {
  transform: scale(.5);
  position: absolute;
  top: -140px;
  right: 0;
  width: 750px;
  height: 1334px;
  transform: scale(.5);
  transform-origin: top right;
}

/* 秋千动画 */
.swing {
  display: block;
  position: absolute;
  left: 226px;
  top: -180.25px;
  width: 478px;
  height: 1038px;
  background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/swing.88545d6c8e1ac798465e367f8e5357ab.png) no-repeat;
  transform-origin: -16.10878661% -29.76878613%;
  /* 设置动画元素的变换原点,以其左上角为基准*/
  animation: ani4_qiuqian 6s cubic-bezier(.455, .03, .515, .955) infinite;
  /* ani4_qiuqian 的动画,时长为6秒,采用 cubic-bezier 缓动函数来定义动画的过渡效果,infinite 表示动画无限循环播放 */
}

/*设置ani4_qiuqian动画*/
@keyframes ani4_qiuqian {
  0% {
    transform: rotateZ(0deg);
  }

  50% {
    transform: rotateZ(31.99359208deg);
  }

  100% {
    transform: rotateZ(0deg);
  }
}

Step3:腿和脚的动画

我们以腿二为示例进行讲解(腿一差不多),位置真难对上呀😭。

image.png

image.png

  1. 腿部定位 :首先,腿部动画通过 .swing .leg2 这一选择器定位在了秋千上,并进行了绝对定位。这个选择器确保了腿部元素能够在页面上准确显示,并且与秋千主体相连。
  2. 设置腿部 :然后,设置了腿部的宽度、高度以及背景图片,使其在页面上呈现出合适的样式。同时,通过 transform-origin 属性,我们指定了腿的旋转中心,这样在动画过程中,腿部的旋转会围绕指定的中心点进行。接着,我们给腿部应用了名为 ani7_leg2 的动画。
  3. 设置腿部动画效果0% 到 25% :在动画开始阶段(0%),腿部初始角度为0度,即不进行任何旋转。然后在动画执行到25%时,腿部向逆时针方向旋转了约 -86.98 度,使得腿部逐渐向后摆动。25% 到 50% :在接下来的动画过程中,从25%到50%,腿部保持在相同的旋转角度,即保持向后摆动的状态。50% 到 75% :在动画执行到50%时,腿部回到了初始的角度,即0度,结束了向后的摆动。75% 到 100% :最后,在动画接近结束的阶段,从75%到100%,腿部再次向逆时针方向旋转了约 -86.98 度,回到了向后摆动的状态。
  4. 设置脚 :最后,使用 .swing .leg2 .jiojio 选择器对脚部进行定位和样式设置,确保脚部能够准确地显示在腿部的位置上,可以随着腿部摆动。
/* 腿动画 */
.swing .leg2 {
  display: block;
  position: absolute;
  left: 185.375px;
  top: 958px;
  width: 130px;
  height: 32px;
  background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg2.d7bc44a91b6974450f2ccc430846c63d.png) no-repeat;
  transform-origin: 91.1538461538462% 33.59375%;
  animation: ani7_leg2 8s ease infinite;
}

@keyframes ani7_leg2 {
  0% {
    transform: rotate(0deg);
  }

  25% {
    transform: rotate(-86.98199658deg);
  }

  50% {
    transform: rotate(0deg);
  }

  75% {
    transform: rotate(-86.98199658deg);
  }

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

.swing .leg2 .jiojio {
  display: block;
  position: absolute;
  background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg2-part.8f70bb7fc789a70bc78c48aa7718a765.png) no-repeat;
  left: -27.75px;
  top: -10.5px;
  width: 57px;
  height: 44px;
}

Step4:头部的动画

image.png

/* 头 */
.swing .head {
  display: block;
  position: absolute;
  left: 451.125px;
  top: 855.5px;
  width: 51px;
  height: 42px;
}

.swing .head {
  background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/head.90bf892023d7df0522a4b53fc07e38df.png) no-repeat;
  animation: ani2_head 8s ease infinite;
}

@keyframes ani2_head {
  0% {
    transform: rotate(0deg);
  }

  25% {
    transform: rotate(-55deg);
  }

  62.5% {
    transform: rotate(-55deg);
  }

  87.92% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(0deg);
  }
}
  1. 头部定位 :我们通过 .swing .head 这一选择器将头部元素定位在了秋千上,并进行了绝对定位。这个选择器确保了头部元素能够在页面上准确显示,并且与秋千主体相连。
  2. 设置头部 :接着,我们设置了头部的宽度、高度以及背景图片,使其在页面上呈现出合适的样式。这一步确保了头部元素能够正确地展现在秋千上,与整体设计保持一致。然后,我们定义了头部的动画效果 ani2_head。这个动画将在8秒的时间内无限循环执行,并且采用了 ease 缓动函数,使得动画变化更加自然。
  3. 设置头部动画效果 :在 0% 处,头部初始角度为0度,即不进行任何旋转。在 25% 处,头部向逆时针方向旋转了约 -55 度,使得头部出现向后倾斜的动作。在 62.5% 处,头部保持在相同的旋转角度,即保持向后倾斜的状态。在 87.92% 处,头部旋转角度回到了初始的0度,结束了向后倾斜的动作。最后,在 100% 处,头部保持在初始角度不进行任何旋转。

最后

上述已经详细介绍代码中的动画部分,下面就让小编附上完整源码吧!

(不知道为什么这个在线音频放进去会运行报错,大家可以把代码拷到自己的编辑器上,知道怎么解决这个问题的小伙伴可以帮忙解答一下,谢谢大家)

如果觉得有所收获的话,麻烦大家给小编一个点赞!