网易云年度总结动画大揭秘!

566 阅读5分钟

前言

你是否曾经对网易云年度总结充满好奇,想要深入了解它是如何生成的?或者你是否想要拥有一份独一无二的年度总结,展示你独特的音乐品味和聆听习惯?

通过代码,我们可以解锁这个神秘的领域,亲手创造出属于自己的网易云年度总结。这不仅是一次技术的挑战,更是一次对自己音乐生活的深入探索。

效果展示

揭秘真相

我们在通过浏览器查看效果时要注意的事项。

  1. 我们要在浏览器右键点击检查。

屏幕截图 2024-04-23 150909.png
  1. 再点击元素左边的这个图标。

屏幕截图 2024-04-23 151055.png

  1. 再选择尺寸,选择iPhone6/7/8

屏幕截图 2024-04-23 151227.png

  1. 如果没有该型号可以点击尺寸后面的倒三角
屏幕截图 2024-04-23 151542.png
  1. 点击修改,在设置中选择iPhone6/7/8进行添加
屏幕截图 2024-04-23 151622.png

音乐播放部分

在点击左上角的音符后,会播放音乐,并且音符会变换成关闭图标。

屏幕截图 2024-04-23 145634.png

当再次点击左上角关闭图标便会关闭音乐,并且将左上角图标变换回原来的音符图标。

屏幕截图 2024-04-23 144211.png

那这是怎么实现的呢?

让我们一起揭秘真相吧。

html部分

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

audio标签用来嵌入音频内容。

music-btn类和off类的div标签用来放置图标。

css部分

.music-btn {
  top: 25px;
  left: 25px;
  z-index: 3;
  position: fixed;
  width: 40px;
  height: 40px;
  background: url(./assert/close.png)
  no-repeat center / cover;
}
.music-btn.off {
  background-image: url(./assert/music.png);
}

我们通过 position: fixed;width: 40px;height: 40px;将图标固定定位在左上角。

通过.music-btn { z-index: 3background: url(./assert/close.png) no-repeat center / cover;}样式和.music-btn.off {background-image: url(./assert/music.png);}样式设置图标。因为.music-btn.off的权重比.music-btn的权重高,所以音符图标样式覆盖了关闭图标样式。

通过z-index: 3;防止图标被覆盖。

JavaScript部分

const musicBtn = document.querySelector('.music-btn');
let defaultMusicPlay = true;
const bgMusic = document.querySelector('#j-bgm');

musicBtn.addEventListener('click', function () {
    if (defaultMusicPlay == true) {
        bgMusic.play();
        musicBtn.classList.remove('off');
        defaultMusicPlay = false;
    }
    else {
        bgMusic.pause();
        musicBtn.classList.add('off');
        defaultMusicPlay = true;
    }
});      

JavaScript的设计思路:

声明一个变量 musicBtn,用于存储通过查询选择器选取的.music-btn 元素;声明一个变量 defaultMusicPlay,并将其初始化为 true;声明一个变量 bgMusic,用于存储通过查询选择器选取的 #j-bgm 元素。

我们可以用一个监听器监听鼠标的点击事件,然后用defaultMusicPlay的值记录音乐播放的状态。defaultMusicPlay为true表示音乐可以播放,defaultMusicPlay为false表示音乐可以关闭。

如果defaultMusicPlay为true则

//播放音乐
bgMusic.play();
//从 musicBtn 元素中移除 off 类名
musicBtn.classList.remove('off');
//将 defaultMusicPlay 的值设置为 false
defaultMusicPlay = false;

我们为什么要移除off类名呢?

当从 .music-btn元素中删除 .off类后,该元素将不再具有与 .off 类相关的样式。这意味着它可能会恢复到之前没有添加 .off类时的样式状态,也就是背景图片为关闭图标的样式。

如果defaultMusicPlay为false则效果相反

//暂停 bgMusic 音频
bgMusic.pause();
//为 musicBtn 元素添加 off 类名
musicBtn.classList.add('off');
//将 defaultMusicPlay 的值设置为 true
defaultMusicPlay = true;

当我们添加.off类后,.music-btn.off样式便会生效。因为.music-btn.off样式的权重比.music-btn样式权重高所以背景图片变换为音符图标。

但是你会发现代码并不简洁。我们可以优化这个代码。

const musicBtn = document.querySelector('.music-btn');
let defaultMusicPlay = true;
const bgMusic = document.querySelector('#j-bgm');

musicBtn.addEventListener('click', function () {
    if (defaultMusicPlay == true) {
        bgMusic.play();
    }
    else {
        bgMusic.pause();
    }
    musicBtn.classList.toggle('off');
    defaultMusicPlay = !defaultMusicPlay;
});      

用defaultMusicPlay = !defaultMusicPlay;也可以实现点击一次改变defaultMusicPlay的值;

toggle可以切换类名,在元素已有的类名中,添加或移除指定的类名。通过toggle('off')切换音乐按钮的'off'类名。

这样我们的代码就得到了简化。

动画部分

动画部分可以由html和css实现。

html部分

<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>
  1. <div class="view special">:这是最外层的容器,具有viewspecial两个类。
  2. <div class="sun">:表示太阳的元素。
  3. <div class="art">:包含人物和秋千的容器。
  4. <div class="swing j-anim03 z-anim">:这是荡秋千的主要元素,有三个类swingj-anim03z-anim
  5. 内部的<div class="leg2"><div class="leg1"><div class="neck"><div class="head">等元素分别表示荡秋千的人物的腿、脖子和头。
  6. 每个部分内部的<div class="jiojio">表示脚。

css部分

@keyframes是 CSS中的一个规则,用于定义动画的关键帧。通过指定不同时间点的样式变化,来实现动画效果。例如:

@keyframes myAnimation {
  0% {
    /* 初始状态的样式 */
  }
  50% {
    /* 中间状态的样式 */
  }
  100% {
    /* 结束状态的样式 */
  }
}
  1. 定义动画名称:使用@keyframes关键字后面跟上动画名称。
  2. 设置关键帧:在大括号内,通过指定不同百分比(代表动画的不同时间点)来设置元素在该时间点的样式。

animation是 CSS中的一个属性,用于设置动画相关的参数,包括动画名称、持续时间、延迟、播放次数、速度曲线等。

要实现 CSS动画,通常可以按照以下步骤进行:

  1. 定义动画关键帧:使用@keyframes规则定义动画在不同时间点的样式变化。
  2. 应用动画:通过animation属性将动画应用到目标元素上,设置动画的名称、持续时间、延迟、播放次数、速度曲线等参数。

荡秋千动画

.swing {
  animation: ani4_qiuqian 6s cubic-bezier(.455,.03,.515,.955) infinite;
}
@keyframes ani4_qiuqian {
  0% {
    transform: rotateZ(0deg);
}
50% {
    transform: rotateZ(31.99359208deg);
}
100% {
    transform: rotateZ(0deg);
}
}

荡秋千动画时长为6秒,使用三次贝塞尔曲线cubic-bezier(.455,.03,.515,.955),并且是无限循环的。在动画关键帧中,0%时旋转角度为0度,50%时旋转角度为31.99359208度,100%时又回到0度。

其余动画都是由@keyframes规则和animation属性实现。

小结

现在,你已经掌握了用代码生成网易云年度总结的方法,快去实践吧,让你的年度音乐记忆以别样的方式呈现出来!