自定义H5音频播放组件样式
背景介绍
简介:audio为html5中的新属性。定义声音,比如音乐或者其他的音频流。
背景:最近在做的警情指挥项目中需要完成一个播放警情录音的功能。组内的小伙伴觉得改原生的样式有些无从下手,所以分享一下具体思路和实现方式供大家参考。该思路和实现方式同样适用于自定义视频播放进度条、按钮等样式。
效果如下,小圆点可拖拽:
设计实现
思路:
H5 的 <audio>
标签是由浏览器负责实现默认样式的。所以不同的浏览器样式不一样,有些还不太美观。所以我们一般会去掉默认样式,自己重新写。具体操作是定义 <audio>
的时候去掉 controls
属性,这样就可以隐藏原生的 audio
, 然后就可以加上自己写的 html + css 代码了。最后用 ref
方式捕获 audio
对象,为它添加各种播放控制事件。
首先大家可以看下手册,里面会介绍一些属性、方法、事件等,后面会用到 www.w3school.com.cn/tags/html_r...
具体实现:
以下代码基于VUE框架
1、已播放进度条样式长度控制
利用vue computed属性根据比例实时计算已播放dom的width
kotlin
computed: {
scaleProgress() {
if (this.scale) {
• return 'width:' + this.scale * 100 + '%';
} else {
• return 'width:0';
}
}
},
2、定义标签和进度条按钮等样式
样式根据视觉稿还原,这部分比较简单,只需关注下关键节点事件方法和变量属性,后续会用到,需要知道这些关键节点需执行的函数。
html代码
ini
<template>
<div class="audio-play">
<audio
ref="audio"
preload
@pause="handlePause"
@play="handleTimeProgress"
@canplay="computedFullTime"
:src="audioUrl"
></audio>
<div class="control-btn" @click="playStatusChange">
<div :class="playStatus ? 'play' : 'stop'"></div>
</div>
<div class="control-line">
<div ref="fullLine" class="bottom-line">
<div class="played-line" :style="scaleProgress"></div>
<div ref="point" class="play-point" @mousedown="handleMouseDown">
<div class="point"></div>
</div>
<div class="played-time">{{ playTime }}</div>
</div>
<div class="al-time">{{ fullTime }}</div>
</div>
</div>
</template>
css代码
xml
<style lang="less">
.audio-play {
height: 18px;
width: 286px;
margin-left: 8px;
display: flex;
.control-btn {
height: 18px;
width: 18px;
.play {
height: 18px;
width: 18px;
background: url('~@/assets/images/alarmCommand/stop.png');
}
.stop {
height: 18px;
width: 18px;
background: url('~@/assets/images/alarmCommand/play.png');
}
}
.control-line {
width: 260px;
margin-left: 6px;
.al-time {
float: right;
opacity: 0.6;
font-family: PingFangSC-Semibold;
font-size: 12px;
color: #78aaff;
margin-top: 4px;
}
.bottom-line {
display: flex;
position: relative;
margin-top: 8px;
height: 4px;
width: 260px;
background: rgba(5, 124, 255, 0.13);
border-radius: 2px;
.played-line {
background-image: linear-gradient(90deg, #43b7fc 0%, #2080f7 93%);
border-radius: 2px;
height: 4px;
// width: 20%;
}
.played-time {
position: absolute;
opacity: 0.6;
font-family: PingFangSC-Semibold;
font-size: 12px;
color: #78aaff;
left: -18px;
top: 10px;
}
.play-point {
position: relative;
height: 10px;
width: 10px;
background: #ffffff;
border: 1px solid #2080f7;
border-radius: 5px;
margin-left: -5px;
margin-top: -3px;
.point {
background: #7fbcff;
height: 4px;
width: 4px;
margin: 2px;
border-radius: 2px;
}
}
}
}
}
</style>
3、播放暂停控制
kotlin
//播放按钮点击切换事件
playStatusChange() {
this.playStatus = !this.playStatus;
if (this.playStatus) {
this.$refs.audio.play();
} else {
this.$refs.audio.pause();
}
}
4、为audio添加播放事件,更新进度条和当前播放时间
@play="handleTimeProgress"
kotlin
handleTimeProgress() {
this.timer = setInterval(this.playing, 1000);
},
playing() {
// 正在播放中
this.scale = this.$refs.audio.currentTime / this.$refs.audio.duration;
this.playTime = this.formatTime(this.$refs.audio.currentTime);
},
5、给audio标签添加暂停事件,清除定时器
@pause="handlePause"
javascript
handlePause() {
this.playStatus = false;
clearInterval(this.timer);
},
6、显示音频总时长
@canplay="computedFullTime" ,根据duration属性获取音频总时长,单位为秒S
formatTime为封装好的一个函数,目的是将秒转换为几分几秒的格式
kotlin
computedFullTime() {
this.fullTime = this.formatTime(this.$refs.audio.duration);
},
formatTime(val) {
val = Math.round(val);
const min = Math.floor(val / 60);
const sec = val % 60;
return this.setZero(min) + ':' + this.setZero(sec);
},
setZero(val) {
if (val < 10) {
return '0' + val;
} else {
return '' + val;
}
}
7、进度条拖拽控制
拖拽小圆点添加鼠标点击事件 @mousedown="handleMouseDown"
ini
//鼠标按下事件触发
handleMouseDown(ev) {
const that = this;
const downX = ev.pageX;
const downL = this.$refs.point.offsetLeft;
//鼠标移动事件
document.onmousemove = ev => {
let scale =
(ev.pageX - downX + downL + 8) / that.$refs.fullLine.offsetWidth;
if (scale < 0) {
scale = 0;
} else if (scale > 1) {
scale = 1;
}
that.scale = scale;
that.$refs.audio.currentTime = scale * that.$refs.audio.duration;
that.playTime = that.formatTime(that.$refs.audio.currentTime);
};
document.onmouseup = () => {
document.onmousemove = document.onmouseup = null;
};
ev.preventDefault();
},
总结
本文介绍到此结束,其实还有好多别的控制,比如音量大小,快退快进等。原理明白后,一切都变得简单。有些时候就是这样,感觉是个庞然大物,其实了解之后并没有想象的复杂。