花潮经典版播放器开发环节之界面设计
本帖最后由 马黑黑 于 2025-3-30 18:07 编辑 <br /><br /><style>.artbox p { margin: 8px 0; }
</style>
<div class="artbox">
<p>先看看本环节的效果,它只是呈现总体设计外观,尚未具备交互功能,可以结合它的效果去理解代码及其解释:</p>
<div id="showBox"></div>
<p>HTML代码是如下这个样子:</p>
<div class="divBox" data-name="HTML代码"><pre class="preBox">
<div class="mplayer" data-time="00:00 00:00">
<div class="btnPlay play"></div>
<div class="progress">
<div class="thumb"></div>
</div>
</div>
</pre></div>
<p>mplayer 是播放器容器。其内,有一个 btnplay 按钮、一个 progress 进度条,后者还带一个子元素 thumb 滑块。另外注意观察:一是容器元素 mplayer 的 data-time 属性,data-* 对应于元素的伪元素属性 attr-*,这意味着设计里头播放器容器元素带一个伪元素用来显示播放时间信息;二是 btnPlay 元素的 class 属性并列使用了两个值,其中 play 指向 CSS 选择器 .play,用于生成按钮外观。</p>
<p>更多设计细节的实现在CSS代码部分完成:</p>
<div class="divBox" data-name="CSS代码"><pre class="preBox">
.mplayer {
position: relative;
width: 300px;
height: fit-content;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
margin: 20px auto;
}
.mplayer::before {
position: absolute;
content: attr(data-time);
width: 100%;
text-align-last: justify;
pointer-events: none;
}
.btnPlay {
width: 20px;
height: 20px;
cursor: pointer;
position: relative;
}
.btnPlay::after {
position: absolute;
content: '';
width: 100%;
height: 100%;
background: red;
clip-path: var(--clip);
}
.progress {
--prg: 0%;
position: relative;
width: 100%;
height: 20px;
display: grid;
place-items: center start;
background: linear-gradient(
90deg,
red var(--prg),
gray var(--prg),
gray 0
) no-repeat center/100% 2px;
padding: 0;
margin: 0;
}
.thumb {
position: absolute;
left: calc(var(--prg) - 10px);
width: 20px;
height: 20px;
background: red;
border: 8px solid green;
border-radius: 50%;
cursor: pointer;
box-sizing: border-box;
}
.play {
--clip: polygon(10% 0,100% 50%,10% 100%);
}
.pause {
--clip: polygon(
35% 0,15% 0,15% 100%,35% 100%,35% 0,
75% 0,75% 100%,55% 100%,55% 0
);
}
</pre></div>
<p>(一)容器元素 mplayer :.mplayer 选择器暂时使用 relative 相对定位,投入应用时应改为 absolute 绝对定位以方便随意安置它,另外 margin 属性临时使用,将来投入生产时删掉。作为播放器容器,它使用的是 flex 弹性布局,并设定了排列方向(flex-direction)、水平对齐方式、间距(gap),以此约束其内子元素的布局。mplayer::before 是 .mplayer 的一个伪元素,它设为绝对定位,在 flex 布局中不会占据空间,默认乖乖呆在该呆的地方——确切说它的左上角坐标点与父容器左上角坐标点相重合;该伪元素宽度设置为宿主元素的100%,然后使用 text-align-last: justify 的属性设置确保其内文本两端对齐;最后,不让它具备指针交互功能(pointer-events),以便让和它可能存在位置重合的元素不会被遮挡。</p>
<p>(二)按钮 btnPlay :.btnPlay 选择器。作为控制音频播放/暂停的按钮,其位置在垂直方向和容器的伪元素重合,但它在水平方向居中,因为,如前已述,父元素设置的相关相关属性 align-items: center 对子元素的水平方向起居中定位约束。btnPlay 按钮使用一个伪元素做形状,出发点是我们要对按钮进行裁剪,被裁剪掉的部分将不接受指针操作,为了确保按钮的交互操作顺畅,不能裁剪按钮自身;其伪元素设置背景色,并使用 CSS变量 --clip 接收剪裁路径,该变量的值将在播放器的交互操作产生时动态改变——这个内容将在下一环节实现,这里暂时通过 HTML 代码的 class 属性给它绑定一个固定值。</p>
<p>(三)进度条 progress :.progress 选择器带一个CSS变量 --prg,该变量用于控制进度指示色长度和滑块的位置。它设置相对定位、采用 grid 网格布局是为了严谨约束子元素 thumb 滑块永远处于垂直居中状态;宽度和父元素 mplayer 一致、高度为20像素;背景色设置一个线性渐变以模拟进度条的进度指示色、底轨色;内边距、外边距均设置为 0 出于精准对齐等层面的考虑。</p>
<p>(四)滑块 thumb :.thumb 选择器是 progress 的子元素,设置 position 属性绝对定位便于动态调整其水平方向的位置;left 左边属性值设为 --prg 变量值减去其宽度的一半以便令其中心点与进度条起点重合;宽高各设为 20 像素;背景色设为红色;边框设为 8 像素、实线、绿色,这样,因为最后一句 box-sizing 属性设为 border-box,这样边框、内边距都算在width里头,所以会留出中心的“圆心”——实际上是滑块宽度被边框挤占后的剩余宽度;鼠标指针是手型。</p>
<p>(五).play 和 .pause 选择器 :用于装载裁剪变量 --clip 的值,留待后续调用。裁剪路径都是使用 polygon 多边形属性实现,前者是三角形(播放)样式,后者是两个纵向排列的矩形(暂停)样式。</p>
<p><br></p>
<p>下一环节 :<a href="https://www.huachaowang.com/forum.php?mod=viewthread&tid=82590" target="_blank">花潮经典版播放器开发环节之功能实现机制(一)</a></p>
</div>
<script type="module">
import hlight from 'https://638183.freep.cn/638183/web/helight/helight1.js';
var divs = document.querySelectorAll('.divBox'),
pres = document.querySelectorAll('.preBox');
divs.forEach((div, key) => hlight.hl(div, pres));
var cssCode = `<style>${pres.textContent}</style>`,
htmlCode = `${pres.textContent}`;
showBox.innerHTML = cssCode + htmlCode;
</script>
这个讲解特别详尽,跟着一项项学习播放器的各种{:4_199:} 这样的播放器包含的东西还不少,有容器(进度时间),还有按钮、进度条、滑块等,
播放器容器带了伪元素用来现实播放时间,伪元素里看到text-align-last: justify两端对齐的命令,这个用得少。
按钮用了使用两个值,“不能裁剪按钮自身”,所以给它弄个伪元素,并绑定了这个值。
进度条还要随着进度变色,这个真不容易。
滑块出来也设置它的颜色,也需要跟着进度走。开始的时候有left: calc(var(--prg) - 10px); 因为它是20,有这个可以让它开始时不会跑到进度条外头,还有box-sizing: border-box;保证它在进度条上。
css里都设定好了,剩下的就是JS的事了吧,对应着这些设定,完成想要它完成事。
这个css设定被黑黑拆解得这么详细,真太好了。{:4_199:}
光是css就这么多内容,到JS里就更难了{:4_173:} 红影 发表于 2025-3-28 21:09
css里都设定好了,剩下的就是JS的事了吧,对应着这些设定,完成想要它完成事。
这个css设定被黑黑拆解得这 ...
CSS总体上逻辑没那么复杂,JS会比较抽象 红影 发表于 2025-3-28 21:06
这样的播放器包含的东西还不少,有容器(进度时间),还有按钮、进度条、滑块等,
播放器容器带了伪元素用 ...
相对而言,CSS没那么难理解,就是细节比较多,所需知识点也不少,CSS知识不全面的要实现起来也会很费劲 红影 发表于 2025-3-28 20:48
这个讲解特别详尽,跟着一项项学习播放器的各种
这里面包含的CSS知识也很丰富的 马黑黑 发表于 2025-3-28 21:53
CSS总体上逻辑没那么复杂,JS会比较抽象
是啊,所以css会相对比较好理解{:4_187:} 马黑黑 发表于 2025-3-28 21:57
相对而言,CSS没那么难理解,就是细节比较多,所需知识点也不少,CSS知识不全面的要实现起来也会很费劲
是的,从这个讲解中就能看出{:4_187:} 马黑黑 发表于 2025-3-28 21:58
这里面包含的CSS知识也很丰富的
是啊,很多都没用过的呢{:4_187:} 看完第一感觉是逻辑严密,这个播放器结构跟钟表一样设计得极其精细,全部用CSS代码书写完成。。{:4_173:} 滑块设计简直是绝了,中间还留一个小点点,这个之前在贴子里见过的,当时就觉得很惊艳
原来要经过这么精心的计算,才有这样的效果。。{:4_173:}
本帖最后由 花飞飞 于 2025-3-29 09:52 编辑
接下来要加上歌词和交互功能。。。
白老师这是让大家伙知其然还要知其所以然。。。
可谓是匠心之作。。天下第一细心之师。{:4_199:}
花飞飞 发表于 2025-3-29 09:51
接下来要加上歌词和交互功能。。。
白老师这是让大家伙知其然还要知其所以然。。。
可谓是匠心之作。。天 ...
歌词可能不再探讨之列,先是交互吧 红影 发表于 2025-3-28 22:41
是啊,很多都没用过的呢
用过应该是用过,没印象 红影 发表于 2025-3-28 22:40
是的,从这个讲解中就能看出
{:4_190:} 花飞飞 发表于 2025-3-29 09:45
看完第一感觉是逻辑严密,这个播放器结构跟钟表一样设计得极其精细,全部用CSS代码书写完成。。
类似的帖子我们有过保姆级的教程,这个呢有侧重点,主要是模拟滑块 花飞飞 发表于 2025-3-29 09:46
滑块设计简直是绝了,中间还留一个小点点,这个之前在贴子里见过的,当时就觉得很惊艳
原来要经过这么精心 ...
有多种实现方式。range那里用的方式不是 borde+width,而是背景 radial-gradient + 其它 马黑黑 发表于 2025-3-29 20:02
用过应该是用过,没印象
是的,很多时候知道它能实现了,就没去认真看,都直接套用了{:4_173:} 马黑黑 发表于 2025-3-29 20:02
css里面的东西还真挺多呢{:4_204:}