600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > vue3封装-自定义audio音频播放【拖拽进度条 点击进度条 快进 后退 音量加减】思路

vue3封装-自定义audio音频播放【拖拽进度条 点击进度条 快进 后退 音量加减】思路

时间:2021-04-11 07:14:24

相关推荐

vue3封装-自定义audio音频播放【拖拽进度条 点击进度条 快进 后退 音量加减】思路

1.根据业务需求反应,及网上阅读资料,代码缺斤少两,本文复制粘贴即可使用,但注意引用了第三库的字体图标,可注释掉替换自己想要的图标即可,其他全手戳代码,可自行优化封装

效果如下:

效果图

1.Audio文件

<template><div class="container"><audio @canplay="getDuration" controls @timeupdate="updateTime" v-show="false" ref="audio":src="audioSrc"/><div class="card"><div class="progress" ref="progress" @click="clickProgress" @mouseup="handleMouseup"><div class="currentProgress" ref="currentProgress"><span class="circle" ref="circle" @mousedown="handleMousedown"></span></div></div><div class="time"><span class="startTime">{{currentDuration }}</span><span class="endTime">{{duration }}</span></div><div class="option"><span class="pre" @click="handleBack"><img src="@/assets/img/快退.png" alt=""> <spanstyle="color: #C7C7C9;font-size: 13px;margin-left: 10px">-{{backSecond }}s</span></span><span class="play" @click="handlePauseOrPlay"><el-icon size="35px" color="#3853FE"><video-pause v-show="!paused"/><video-play v-show="paused"/></el-icon></span><span class="next" @click="handleForward"><span style="color: #C7C7C9;font-size: 13px;margin-right: 10px">+{{forwardSecond }}s </span><img src="@/assets/img/快进.png" alt=""></span><div class="volumePanel"><lk-select v-model:visible="volumeVisible"><template v-slot:reference><img class="volume" v-if="volume > 0" src="@/assets/img/24gf-volumeHigh.png" alt=""><img class="volume" v-else src="@/assets/img/24gf-volumeCross.png" alt=""></template><div class="progressY" ref="progressY"><div class="currentProgressY" ref="currentProgressY"><span class="circleY" ref="circleY" @mousedown="handleVolumeMousedown"></span></div></div></lk-select></div></div></div></div></template><script>import {VideoPause, VideoPlay } from '@element-plus/icons-vue'import lkSelect from '../dropdown/lk-select'export default {name: "index",components: {VideoPause, VideoPlay, lkSelect },props: {audioSrc: {type: String,default: 'https://img-/Audio//02/06/08/0206081849_A100187_34f7e6b8-thumb.mp3'},backSecond: {type: Number,default: 3},forwardSecond: {type: Number,default: 10}},data() {return {duration: '00:00',currentDuration: '00:00',audio: '',volume: 1,paused: true,isMoveIn: false, //是否在移动中showVolumePanel: false,volumeVisible: false}},methods: {//后退handleBack() {if (this.audio.currentTime > this.backSecond) {this.audio.currentTime = this.audio.currentTime - this.backSecond}},//前进handleForward() {if (this.audio.duration - this.audio.currentTime > this.forwardSecond) {this.audio.currentTime = this.audio.currentTime + 10}},//暂停或播放handlePauseOrPlay() {this.audio.paused ? this.audio.play() : this.audio.pause()this.paused = !this.paused},//视频在可以播放时触发getDuration() {this.duration = this.timeFormat(this.$refs.audio.duration)this.audio = this.$refs.audiothis.audio.volume = this.volume //默认百分百音量//监听音量的变化// this.audio.addEventListener('volumechange',(value)=>{// console.log(this.audio.volume)// })},//将单位为秒的的时间转换成mm:ss的形式timeFormat( number ) {let minute = parseInt(number / 60);let second = parseInt(number % 60);minute = minute >= 10 ? minute : "0" + minute;second = second >= 10 ? second : "0" + second;return minute + ":" + second;},//进度条发生变化时触发updateTime() {if (!this.$refs.progress) returnthis.currentDuration = this.timeFormat(this.audio.currentTime)//如果不是正在移动 和 没有暂停播放就执行if (!this.isMoveIn || !this.audio.paused) {// 设置当前时间let MoveX = this.$refs.progress.clientWidth * ( this.audio.currentTime / this.audio.duration )//播放时更新距离this.$refs.currentProgress.style.width = MoveX + 'px'this.$refs.circle.style.left = MoveX - ( this.$refs.circle.clientWidth / 2 ) + 'px'}},//点击进度条更新进度clickProgress( e ) {//如果不是正在移动 和 没有暂停播放就执行if (!this.isMoveIn || !this.audio.paused) {this.updateProgress(e.offsetX)}},//更新进度updateProgress( MoveX ) {//当前移动的位置 = 当前移动的位置 / 当前进度条的可视长度 //this.$refs.progress.clientWidth 注意一定要拿总长度 否则会拿进度条已经走过的长度let clickProgress = ( MoveX / this.$refs.progress.clientWidth )//设置播放的时间 = 总时长 * 当前点击的长度this.audio.currentTime = this.audio.duration * clickProgress//设置移动的位置this.$refs.currentProgress.style.width = MoveX + 'px'this.$refs.circle.style.left = MoveX - ( this.$refs.circle.clientWidth / 2 ) + 'px'},//更新音量进度updateVolumeProgress(MoveY){//得到音量 【0 - 1】 区间const volume = ((this.$refs.currentProgressY.clientHeight / 60) * 100 / 100).toFixed(1)this.audio.volume = volumethis.volume = volume//移动音量条this.$refs.currentProgressY.style.height = MoveY + 'px'//移动小圆圈this.$refs.circleY.style.Top = MoveY - ( this.$refs.circleY.clientHeight / 2 ) + 'px'},//鼠标弹起handleMouseup() {setTimeout(() => {this.audio.play()this.paused = falsethis.isMoveIn = false}, 200)},//调整进度handleMousedown() {this.audio.pause()this.paused = truethis.isMoveIn = truelet progress = this.$refs.progress//进度条 左 边距离页面左边的距离 移动最小值let moveMin = progress.offsetParent.offsetLeft + progress.offsetLeft//进度条 右 边距离页面左边的距离 移动最大值let moveMax = progress.offsetParent.offsetLeft + progress.offsetLeft + progress.clientWidth//小圆圈的宽度let circleWidth = ( this.$refs.circle.clientWidth / 2 )let moveX = ( e ) => {if (e.pageX >= moveMax) {return} else if (e.pageX <= moveMin) {return}this.$refs.circle.style.left = e.pageX - moveMin - circleWidth + 'px'this.updateProgress(e.pageX - moveMin)}//获取当前鼠标的位置 Xdocument.addEventListener('mousemove', moveX)//鼠标弹起来document.addEventListener('mouseup', () => {document.removeEventListener('mousemove', moveX)})},//调整音量handleVolumeMousedown(){let progressY = this.$refs.progressY//音量的最小值let moveMin = progressY.offsetParent.offsetTop//音量的最大值let moveMax = progressY.offsetParent.offsetTop + progressY.clientHeight//小圆圈的高度let circleHeight = ( this.$refs.circleY.clientHeight / 2 )let moveY = ( e ) => {//禁止移动时复制内容e.preventDefault()if (e.pageY >= moveMax) {return} else if (e.pageY <= moveMin) {return}this.$refs.circleY.style.top = e.pageY - moveMin - circleHeight + 'px'this.updateVolumeProgress(e.pageY - moveMin)}//获取当前鼠标的位置 Xdocument.addEventListener('mousemove', moveY)//鼠标弹起来document.addEventListener('mouseup', () => {document.removeEventListener('mousemove', moveY)})}}}</script><style scoped lang="less">.card {width: 300px;padding: 30px;box-shadow: 0 0 10px 10px rgba(0, 0, 0, 0.03);border-radius: 10px;.volumePanel {.volume {width: 20px;padding-top: 5px;}.volumeOption {cursor: pointer;}}.progress, .progressY {height: 7px;border-radius: 3px;margin-bottom: 5px;width: 100%;background-color: #DADFEA;cursor: pointer;.currentProgress, .currentProgressY {position: relative;height: 100%;width: 0;background-color: #3853FE;border-radius: 3px;.circle, .circleY {position: absolute;right: -6px;top: -2px;display: inline-block;width: 10px;height: 10px;border-radius: 50%;border: 1px solid #3853FE;background-color: #fff;&:hover {width: 12px;height: 12px;top: -3px;border-radius: 50%;}}}}.progressY {width: 7px;height: 60px;margin: 10px;.currentProgressY{height: 100%;width: 100%;.circleY {bottom:-2px;right: -3px;top: unset;&:hover {width: 12px;height: 12px;bottom: -2px;top: unset;border-radius: 50%;}}}}.time {display: flex;justify-content: space-between;color: #777A85;font-size: 12px;}.option {display: flex;justify-content: space-between;align-items: center;padding: 20px 30px 0 30px;.play, .pre, .next {display: flex;padding: 0 2px;align-items: center;cursor: pointer;}}}</style>

2.lk-select文件

<template><div class="lk-select"><div ref="reference" @click="showPopper" ><slot name="reference"/></div><div ref="Popper" class="Popper" v-show="visible"><slot/></div></div></template><script setup>import {watch, ref, nextTick ,onUnmounted} from 'vue'const emits = defineEmits(['update:visible'])const props = defineProps({visible: [Boolean, String]})const reference = ref()const Popper = ref()watch(() => props.visible, ( newValue ) => {if (newValue) {nextTick(() => {const {left, top, height} = reference.value.getBoundingClientRect()Popper.value.style.left = left + 'px'Popper.value.style.top = top + height + 'px'})window.addEventListener('mousedown',docClick)}else {window.removeEventListener('mousedown',docClick)}})function docClick(e){//如果点击的是音量 或者 是音量面板 则 不隐藏音量面板if (Popper.value.contains(e.target) || reference.value.contains(e.target)){return}emits('update:visible', false)}function showPopper() {emits('update:visible', !props.visible)}onUnmounted(()=>{emits('update:visible', false)})defineExpose({showPopper})</script><style scoped>.lk-select {cursor: pointer;position: relative;}.Popper {position: fixed;top: 0;left: 0;background: #fff;box-shadow: 0 2px 12px 0px rgba(0, 0, 0, 0.1);}</style>

拒绝白票,从我做起,对你有思路就动动小指头点个start,收藏关注哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。