前言
在过去的一年里,我们通过网易云音乐体验了无数的旋律和节奏,它们陪伴我们度过了不同的时刻。如今,随着年度听歌报告的发布,我们有机会以一种全新的方式——通过JavaScript——来回顾这段音乐旅程。在这篇文章中,我们将探索如何利用JavaScript的强大功能来捕捉和呈现我们的音乐足迹,从而创建一个个性化且互动性强的年度听歌报告。我们将从数据的获取和处理开始,逐步深入到可视化的实现,最终展示一个既美观又富有信息量的报告。让我们开始这段代码与音符交织的旅程吧。
正文
- 我们在实现这个动态效果时,先思考一下这个动画中具有哪些元素呢
- 首先我们看html片段,用于展示一个年度听歌报告页面的基本结构和样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>年度听歌报告</title>
<link rel="icon" href="https://s1.music.126.net/style/favicon.ico">
<link rel="stylesheet" href="./index.css">
</head>
<body>
<audio id="j-bgm" src="./assert/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">11月11日</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">10次</em>
</p>
</div>
</div>
</body>
</html>
-
<!DOCTYPE html>:声明文档类型为HTML5。 -
<html lang="en">:HTML文档的根元素,指定了语言为英文。 -
<head>:文档的头部,包含了一些元数据和引用的外部资源。meta标签包含了字符编码、视口设置以及IE兼容性设置。title标签定义了页面的标题。link标签用于引入外部资源,这里引入了一个图标文件和一个样式表。
-
<body>:文档的主体部分,包含了页面的实际内容。<audio>元素定义了一个音频播放器,指定了音频文件的路径。<div>元素包含了一个音乐按钮,初始状态为关闭。<div>元素包含了一个特殊视图,展示了一个动画和一些特殊内容。
-
特殊视图包含了以下元素:
<div class="art">:用于绘制动画的容器。- 动画部分包含了一个人在荡秋千,通过DIV和CSS样式来实现。
<div class="paras">:包含了一些特殊内容的容器,其中有几个段落标签,展示了一些特殊日期和听歌行为。
整体来说,这段代码是一个简单的HTML页面,主要用于展示一个年度听歌报告,通过HTML和CSS来实现一些动画效果和特殊内容的展示。
- 在html完成一个年度听歌报告页面的基本结构和样式我们该如何使用CSS和js来实现动画效果呢?
* {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
/* music 按钮 */
.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);
}
.view {
width: 100%;
height: 100%;
overflow: hidden;
}
/* 第二屏 特殊 view special*/
.view.special {
position: absolute;
background-image:
linear-gradient(60deg,#f8ddd1,#faece5 73%,#fad2c0);
}
/* 中间太阳 */
.sun {
position: absolute;
top: 45%;
width: 283px;
height: 283px;
background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/sun.a3f575ae2fef2cfdae15011e6081a094.png) no-repeat;
background-size: 100%;
left: 50%;
transform: translate(-50%,-50%);
}
/* 秋千 外层压缩 */
.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;
}
@keyframes ani4_qiuqian {
0% {
transform: rotateZ(0deg);
}
50% {
transform: rotateZ(31.99359208deg);
}
100% {
transform: rotateZ(0deg);
}
}
/* 腿动画 */
.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;
}
.swing .leg1 {
display: block;
position: absolute;
left: 290.375px;
top: 955.25px;
width: 63px;
height: 130px;
background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg1.b1df6a7d1a794d36fbd0e1277733e1cf.png) no-repeat;
transform-origin: 17.8571428571429% 13.3653846153846%;
animation: ani5_leg1 8s ease infinite;
}
@keyframes ani5_leg1 {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(108.97744399deg);
}
50% {
transform: rotate(0deg);
}
75% {
transform: rotate(108.97744399deg);
}
100% {
transform: rotate(0deg);
}
}
/* 腿的一部分 */
.leg1 .jiojio {
display: block;
position: absolute;
left: 26.25px;
top: 102.5px;
width: 39px;
height: 62px;
background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg1-part.f2f17703a6af8fd2af5e0f5a9f320623.png) no-repeat;
}
.swing .neck {
position: absolute;
left: 451.125px;
top: 855.5px;
width: 51px;
height: 42px;
background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/neck.07a0013beff9796ed79c2cea542e5af2.png) no-repeat;
}
/* 头 */
.swing .neck, .swing .head {
display: block;
position: absolute;
left: 451.125px;
top: 855.5px;
width: 51px;
height: 42px;
}
/* 脖子 */
.swing .neck {
background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/neck.07a0013beff9796ed79c2cea542e5af2.png) no-repeat;
}
/* 头 */
.swing .head {
background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/head.90bf892023d7df0522a4b53fc07e38df.png) no-repeat;
animation: ani2_head 8s ease infinite;
}
/* 头发 */
.swing .head .part {
background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/head-part.22d4381c4bd6cb1c3afd2b1bfcfe22f1.png) no-repeat;
left: 20px;
top: 2px;
width: 40px;
height: 47px;
position: absolute;
}
@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);
}
}
/* 特殊的内容 */
.paras {
bottom: 110px;
left: 10.67%;
position: absolute;
line-height: 1.6667;
letter-spacing: 1px;
color: #333;
}
.s-fcRed {
color: #df493a;
}
.z-enter .f-animLineUp {
opacity: 1;
transform: translateY(0);
transition: opacity 1.2s,transform 1s;
}
.f-animLineUp {
opacity: 0;
transform: translateY(6px);
}
em, i {
font-style: normal;
text-align: left;
}
这段CSS代码定义了页面的样式和动画效果:
* { margin: 0; padding: 0; }: 这段CSS代码将所有元素的外边距和内边距都设置为0,以确保页面在不同浏览器中具有一致的外观。html, body { width: 100%; height: 100%; }: 这段CSS代码将HTML和body元素的宽度和高度设置为100%,以确保页面占据整个浏览器窗口的空间。.music-btn: 定义了音乐按钮的样式,包括位置、大小和背景图片。.music-btn.off: 当音乐按钮处于关闭状态时,修改了背景图片。.view和.view.special: 定义了页面视图的样式,包括尺寸和溢出隐藏。.sun: 定义了太阳的样式,包括位置、大小和背景图片。.art: 定义了秋千的样式,包括位置、大小和背景图片。.swing: 定义了秋千的动画效果,包括位置、大小、背景图片和动画属性。.swing .leg2和.swing .leg1: 定义了秋千的腿部动画效果,包括位置、大小、背景图片和动画属性。.swing .neck和.swing .head: 定义了秋千的脖子和头部的样式,包括位置和大小。.swing .head .part: 定义了头部的部分(头发)的样式,包括位置、大小和背景图片。.paras: 定义了特殊内容的样式,包括位置、行高、字母间距和颜色。.s-fcRed: 定义了红色文字的颜色。.z-enter .f-animLineUp和.f-animLineUp: 定义了一种动画效果,当元素进入视图时,其透明度和垂直方向的位移会发生变化。em, i: 定义了斜体文本的样式。
这些CSS代码一起定义了页面的布局、样式和动画效果,使得页面具有吸引人的外观和交互性。
- 最后我们来展示一下js部分
<script>
const viewSpecial = document.querySelector('.view .paras');
const musicBtn = document.querySelector('.music-btn');
let defaultMusicPlay = true;
const bgMusic = document.querySelector('#j-bgm');
musicBtn.addEventListener('click', () => {
if (defaultMusicPlay) {
bgMusic.play();
} else {
bgMusic.pause();
}
defaultMusicPlay = !defaultMusicPlay;
musicBtn.classList.toggle('off');
});
setTimeout(() => {
viewSpecial.classList.add('z-enter')
}, 1000)
</script>
这段JavaScript代码添加了一些交互功能到页面中:
const viewSpecial = document.querySelector('.view .paras');: 这行代码选中了页面中的特殊内容容器。const musicBtn = document.querySelector('.music-btn');: 这行代码选中了页面中的音乐按钮。let defaultMusicPlay = true;: 这行代码定义了一个变量defaultMusicPlay,用来追踪音乐播放状态,默认为true,表示音乐播放中。const bgMusic = document.querySelector('#j-bgm');: 这行代码选中了页面中的背景音乐元素。musicBtn.addEventListener('click', () => { ... });: 这段代码添加了一个点击事件监听器,当音乐按钮被点击时执行相应的操作。- 在点击事件处理函数中,根据当前音乐播放状态,切换音乐的播放和暂停,并更新音乐按钮的样式。
setTimeout(() => { viewSpecial.classList.add('z-enter') }, 1000): 这段代码设置了一个定时器,在一秒后给特殊内容容器添加一个z-enter类,触发特殊内容的进入动画效果。
这些JavaScript代码增加了音乐播放控制功能和特殊内容的进入动画效果,使得页面更具交互性和吸引力。
结尾
在这篇文章中,我们通过使用 JavaScript 实现了一个简单的网易云音乐年度听歌报告页面。通过 HTML、CSS 和 JavaScript 的组合,我们展示了如何创建一个具有动态效果和交互功能的页面,让用户可以点击按钮控制音乐的播放和暂停,并观看到特殊内容的进入动画。这个项目不仅仅是一个技术实践,更是一个展示了如何利用前端技术创造出有趣、吸引人的网页体验的例子。希望本文能够对你了解如何利用 JavaScript 实现网易云音乐年度听歌报告有所帮助。如果你有任何问题或建议,欢迎在下方留言,谢谢阅读!