先看看本环节的效果,它只是呈现总体设计外观,尚未具备交互功能,可以结合它的效果去理解代码及其解释:
HTML代码是如下这个样子:
<div class="mplayer" data-time="00:00 00:00">
<div class="btnPlay play"></div>
<div class="progress">
<div class="thumb"></div>
</div>
</div>
mplayer 是播放器容器。其内,有一个 btnplay 按钮、一个 progress 进度条,后者还带一个子元素 thumb 滑块。另外注意观察:一是容器元素 mplayer 的 data-time 属性,data-* 对应于元素的伪元素属性 attr-*,这意味着设计里头播放器容器元素带一个伪元素用来显示播放时间信息;二是 btnPlay 元素的 class 属性并列使用了两个值,其中 play 指向 CSS 选择器 .play,用于生成按钮外观。
更多设计细节的实现在CSS代码部分完成:
.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
);
}
(一)容器元素 mplayer :.mplayer 选择器暂时使用 relative 相对定位,投入应用时应改为 absolute 绝对定位以方便随意安置它,另外 margin 属性临时使用,将来投入生产时删掉。作为播放器容器,它使用的是 flex 弹性布局,并设定了排列方向(flex-direction)、水平对齐方式、间距(gap),以此约束其内子元素的布局。mplayer::before 是 .mplayer 的一个伪元素,它设为绝对定位,在 flex 布局中不会占据空间,默认乖乖呆在该呆的地方——确切说它的左上角坐标点与父容器左上角坐标点相重合;该伪元素宽度设置为宿主元素的100%,然后使用 text-align-last: justify 的属性设置确保其内文本两端对齐;最后,不让它具备指针交互功能(pointer-events),以便让和它可能存在位置重合的元素不会被遮挡。
(二)按钮 btnPlay :.btnPlay 选择器。作为控制音频播放/暂停的按钮,其位置在垂直方向和容器的伪元素重合,但它在水平方向居中,因为,如前已述,父元素设置的相关相关属性 align-items: center 对子元素的水平方向起居中定位约束。btnPlay 按钮使用一个伪元素做形状,出发点是我们要对按钮进行裁剪,被裁剪掉的部分将不接受指针操作,为了确保按钮的交互操作顺畅,不能裁剪按钮自身;其伪元素设置背景色,并使用 CSS变量 --clip 接收剪裁路径,该变量的值将在播放器的交互操作产生时动态改变——这个内容将在下一环节实现,这里暂时通过 HTML 代码的 class 属性给它绑定一个固定值。
(三)进度条 progress :.progress 选择器带一个CSS变量 --prg,该变量用于控制进度指示色长度和滑块的位置。它设置相对定位、采用 grid 网格布局是为了严谨约束子元素 thumb 滑块永远处于垂直居中状态;宽度和父元素 mplayer 一致、高度为20像素;背景色设置一个线性渐变以模拟进度条的进度指示色、底轨色;内边距、外边距均设置为 0 出于精准对齐等层面的考虑。
(四)滑块 thumb :.thumb 选择器是 progress 的子元素,设置 position 属性绝对定位便于动态调整其水平方向的位置;left 左边属性值设为 --prg 变量值减去其宽度的一半以便令其中心点与进度条起点重合;宽高各设为 20 像素;背景色设为红色;边框设为 8 像素、实线、绿色,这样,因为最后一句 box-sizing 属性设为 border-box,这样边框、内边距都算在width里头,所以会留出中心的“圆心”——实际上是滑块宽度被边框挤占后的剩余宽度;鼠标指针是手型。
(五).play 和 .pause 选择器 :用于装载裁剪变量 --clip 的值,留待后续调用。裁剪路径都是使用 polygon 多边形属性实现,前者是三角形(播放)样式,后者是两个纵向排列的矩形(暂停)样式。
下一环节 :花潮经典版播放器开发环节之功能实现机制(一)