简言:
网易的年度听歌报告生动而有趣,独属的动画LOGO飘逸洒脱,字幕的渐变插入,按键的巧妙布局,背景的颜色变化,中心的点缀,以及懂你的歌曲联播...今天就设计一个浅简的网易页面布局。
HTML
根据页面所示:构建页面中的身体部落,定义各个部位名
<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>
<audio id="j-bgm" src="./assert/bgm.mp3"></audio>
:这是一个音频元素,通过id属性为其指定了一个标识符"j-bgm"。该音频元素引用了名为"bgm.mp3"的音频文件,路径为"./assert/bgm.mp3"。这个音频元素用于在网页上播放背景音乐。<div class="music-btn off"></div>
:这是一个div元素,具有"class"属性,其中包含了两个类名"music-btn"和"off"。这个div元素可能是用于控制音乐播放的按钮,"off"类可能表示按钮当前处于关闭状态。<div class="view special">...</div>
:这是一个div元素,具有"class"属性,并包含了一些子元素,用于创建动画效果。其中可能包含了一些CSS类或JavaScript类来实现动画的效果。在这个div内部可能是一个场景的描述,类名"special"可能表示这个场景具有特殊的特征。- 在
<div class="view special">...</div>
内部包含了一些div元素,用于创建动画效果。这些div元素可能是动画的组成部分,通过CSS或JavaScript来控制它们的动态效果。其中可能包含了"荡秋千"场景的描述,以及一些用于描述人物动作的div元素,如"swing"、"leg1"、"leg2"、"neck"和"head"等。
其次,插入报告总结,在HTML中用P标签输入对应的内容即可
<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 class="paras">...</div>
:这是一个div元素,具有"class"属性为"paras",用于包裹一系列段落文本。 -
<p class="para f-animLineUp" style="transition-delay: 0.2s;">...</p>
:这是一个段落元素,具有"class"属性为"para"和"f-animLineUp",这两个类可能用于指定段落的样式和动画效果。在内联样式中使用了"transition-delay"属性,设置了动画延迟时间为0.2秒。段落内部包含了一个<em>
元素,用于强调文本内容,并且具有"class"属性为"s-fcRed",可能用于设置文本颜色为红色。这个段落可能用于显示日期信息,"11月11日"。 -
接下来的几个段落元素
<p class="para f-animLineUp" style="transition-delay: ...">...</p>
也具有相似的结构,它们显示了一些文本内容,并应用了相同的CSS动画效果"f-animLineUp"。每个段落的动画延迟时间逐渐增加,分别为0.3秒、0.4秒、0.5秒和0.6秒,以创建一个逐行渐现的效果。 -
在其中的某个段落中包含了一个
<em>
元素,用于强调文本内容,具有"class"属性为"s-fcRed",可能用于设置文本颜色为红色。这个<em>
元素内部包含了一些歌曲标题或数字,如"《被伤过的心还可以爱谁》"和"10次"。
不单独构建JS进行引用,在HTML中用scipt标签来摄取
<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>
根据各个组件的命名进行调用,进行页面的实操和动态效果。
-
const viewSpecial = document.querySelector('.view .paras');
:这行代码使用了document.querySelector
方法,通过CSS选择器获取了页面中具有"class"属性为"view"的元素下的"class"属性为"paras"的元素,并将其赋值给变量viewSpecial
。 -
const musicBtn = document.querySelector('.music-btn');
:这行代码同样使用了document.querySelector
方法,获取了页面中具有"class"属性为"music-btn"的元素,并将其赋值给变量musicBtn
。 -
let defaultMusicPlay = true;
:这行代码定义了一个变量defaultMusicPlay
,用于记录音乐是否处于播放状态,默认为true,表示音乐初始状态是播放的。 -
const bgMusic = document.querySelector('#j-bgm');
:这行代码获取了页面中具有"id"属性为"j-bgm"的音频元素,并将其赋值给变量bgMusic
。 -
musicBtn.addEventListener('click', () => { ... });
:这是一个事件监听器,用于监听音乐按钮(musicBtn
)的点击事件。当音乐按钮被点击时,会执行后面的箭头函数中的代码。 -
if (defaultMusicPlay) { bgMusic.play(); } else { bgMusic.pause(); }
:在点击事件中,根据defaultMusicPlay
的值判断音乐当前是否正在播放。如果正在播放,则暂停音乐;如果未播放,则开始播放音乐。 -
defaultMusicPlay = !defaultMusicPlay;
:在点击事件中,将defaultMusicPlay
的值取反,以记录音乐的当前播放状态。 -
musicBtn.classList.toggle('off');
:在点击事件中,切换音乐按钮的类名,如果原先有"off"类,则移除,如果原先没有"off"类,则添加,以改变音乐按钮的样式或状态。 -
setTimeout(() => { viewSpecial.classList.add('z-enter') }, 1000)
:这行代码使用了setTimeout
函数,在页面加载后延迟1秒执行,将给定元素viewSpecial
添加类名"z-enter"。这可能是用于触发某种动画效果,如渐现或滑入效果。
CSS
实现对应的动态效果
* {
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
}
布置前先构建全局的样式。
* { margin: 0; padding: 0; }
:这是一个通用选择器("*"),用于选择页面中的所有元素。设置了所有元素的margin
和padding
属性值为0,这意味着去除了所有元素的外边距和内边距,使页面内容与浏览器窗口边缘之间没有任何空白间隙。html, body { width: 100%; height: 100%; }
:这行代码选择了html元素和body元素,并为它们设置了宽度和高度均为100%。这意味着网页的html根元素和body元素将会占据整个浏览器窗口的宽度和高度,确保页面的内容占据整个可视区域。这通常用于确保页面布局的响应性和一致性。
/* music 按钮 */
.music-btn {
top: 25px;
left: 25px;
z-index: 3;
position: absolute;
width: 40px;
height: 40px;
background: url(./assert/close.png) no-repeat center / cover;
}
.music-btn.off {
background-image: url(./assert/music.png);
}
先拿按钮进行举例
这段CSS代码定义了一个名为.music-btn
的样式规则,用于设置页面中音乐按钮的外观和位置。
-
.music-btn { ... }
:这是一个类选择器,用于选择具有"class"属性为"music-btn"的元素,并设置其样式。-
top: 25px; left: 25px;
:将音乐按钮的位置设置在距离父元素顶部和左侧各25像素的位置,这使得音乐按钮位于页面的左上角位置。 -
z-index: 3;
:设置音乐按钮的层级为3,确保它位于其他元素之上,以便在页面上可见。 -
position: absolute;
:将音乐按钮的定位方式设置为绝对定位,使其相对于最近的已定位祖先元素(通常是body元素)进行定位。 -
width: 40px; height: 40px;
:设置音乐按钮的宽度和高度分别为40像素,这通常是一个合适的尺寸用于按钮。 -
background: url(./assert/close.png) no-repeat center / cover;
:设置音乐按钮的背景样式为从"./assert/close.png"路径引用的图像,设置背景图像不重复(no-repeat),并且将其居中(center)显示,并让背景图像覆盖整个按钮区域(cover)。
-
-
.music-btn.off { ... }
:这是另一个类选择器,用于选择具有"class"属性为"music-btn"和"off"的元素,并设置其样式。通常是在音乐按钮被关闭时应用的样式。background-image: url(./assert/music.png);
:将音乐按钮的背景图像更改为从"./assert/music.png"路径引用的图像,这可能是一个表示音乐开关的图标,用于在音乐暂停或关闭时显示。
基于此,进行其他部位的类推,例如leg,head,swing。
对于动画效果的展示:使用@keyframes 加上类名进行创建
@keyframes ani4_qiuqian {
0% {
transform: rotateZ(0deg);
}
50% {
transform: rotateZ(31.99359208deg);
}
100% {
transform: rotateZ(0deg);
}
}
这段代码定义了一个名为ani4_qiuqian
的关键帧动画(Keyframes Animation),用于创建一个旋转动画效果。
-
@keyframes ani4_qiuqian { ... }
:这是关键帧动画的声明,ani4_qiuqian
是动画的名称。 -
0% { transform: rotateZ(0deg); }
:在动画的起始状态(0%)时,元素没有旋转,transform
属性的rotateZ(0deg)
将元素绕着Z轴旋转0度,即保持不动。 -
50% { transform: rotateZ(31.99359208deg); }
:在动画进行到50%时,元素绕着Z轴旋转31.99359208度。这表示元素在旋转过程中达到了一半的旋转角度。 -
100% { transform: rotateZ(0deg); }
:在动画结束状态(100%)时,元素回到原始状态,绕着Z轴旋转0度,即保持不动,完成了一次完整的旋转。
通过定义这些关键帧,可以创建一个周期性的旋转动画效果,元素将会从起始状态逐渐旋转到一定角度,然后再回到起始状态,形成一种往复的动画效果。
基于此依次进行构建布局,对于每段代码的解读这里就不再缀续了,直接附上全部代码
* {
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
}
/* music 按钮 */
.music-btn {
top: 25px;
left: 25px;
z-index: 3;
position: absolute;
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;
}
以上便能实现全部动态效果的实现了。
结尾
这里总结几点要素:
对于部位的要素位置,要学会灵活使用定位的布局,防止按键的失联。
动画记得循环的时间节点,可以尽可能详细。
按钮页面的布局,防止失效。