H5新特性audio音频怎么做,PC以及移动端的进度条拖拽怎么做

本文详细介绍了如何使用Vue.js实现一个响应式音频播放进度条,支持移动端和PC端的拖拽操作,以及处理触摸事件和鼠标事件以控制音频播放进度。
摘要由CSDN通过智能技术生成

音频

function updateTime(e) {

    if (!progressChanging.value) {

        currentTime.value = e.target.currentTime

    }

}

进度条:

function onProgressChanging(progress) {

    progressChanging.value = true

    isPlay.value = false

    currentTime.value = duration.value * progress

}

function onProgressChanged(progress) {

    progressChanging.value = false

    isPlay.value = true

    audioRef.value.currentTime = currentTime.value = duration.value * progress

}

<template>
  <div class="progress-bar" ref="progressBarRef" @click="onClick">
    <div class="bar-inner">
      <div class="progress" ref="progressRef" :style="progressStyle"></div>
      <!-- 移动端 -->
      <div v-if="isMobile == true" class="progress-btn-wrapper" :style="btnStyle"
        @touchstart.prevent="onTouchStart($event)" @touchmove.prevent="onTouchMove($event)"
        @touchend.prevent="onTouchEnd">
        <div class="progress-btn"></div>
      </div>
      <!-- PC端 -->
      <div v-if="isMobile == false" ref="btnWrapperRef" class="progress-btn-wrapper" :style="btnStyle"
        @mousedown.prevent="onMouseDown($event)" @mousemove.prevent @mouseup.prevent="onMouseUp">
        <div class="progress-btn"></div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, defineProps, watch, computed, onMounted } from 'vue'

const offset = ref(0)
const progressRef = ref()
const progressBarRef = ref()
const progressBtnWidth = 16
const btnWrapperRef = ref()
const touch: any = {}
const mouse: any = {}
const isMobile = ref(false)
const mouseup_click_debug = ref(false)
const props = defineProps({
  progress: {
    type: Number,
    default: 0
  }
})
const emits = defineEmits(['progress-changing', 'progress-changed'])
onMounted(() => {
  if (window.innerWidth <= 768) {
    isMobile.value = true
  } else {
    isMobile.value = false
  }
})
watch(() => props.progress, (newVal, oldVal) => {
  //计算总进度条,除去按钮宽度
  const barWidth = progressBarRef.value.clientWidth - progressBtnWidth
  //计算出当前音频进度
  offset.value = barWidth * newVal
})

const progressStyle = computed(() => {
  //将当前音频进度style更换
  return `width:${offset.value}px`
})
const btnStyle = computed(() => {
  //按钮偏移量
  return `transform:translate3d(${offset.value}px,0,0)`
})
//移动端进度条拖拽第一步点击
function onTouchStart(e) {
  touch.x1 = e.touches[0].pageX
  touch.beginWidth = progressRef.value.clientWidth
}
//移动端拖拽移动
function onTouchMove(e) {
  const delta = e.touches[0].pageX - touch.x1
  const tempWidth = touch.beginWidth + delta
  const barWidth = progressBarRef.value.clientWidth - progressBtnWidth
  const progress = Math.min(1, Math.max(tempWidth / barWidth, 0))
  offset.value = barWidth * progress
  //传递给父组件的进度
  emits('progress-changing', progress)
}
//移动端拖拽移动结束
function onTouchEnd() {
  const barWidth = progressBarRef.value.clientWidth - progressBtnWidth
  const progress = progressRef.value.clientWidth / barWidth
  emits('progress-changed', progress)
}
//PC端鼠标点击
function onMouseDown(e) {
  mouse.x1 = e.pageX
  mouse.beginWidth = progressRef.value.clientWidth
  document.onmousemove = function (e) {
    const delta = e.pageX - mouse.x1
    const tempWidth = mouse.beginWidth + delta
    const barWidth = progressBarRef.value.clientWidth - progressBtnWidth
    const progress = Math.min(1, Math.max(tempWidth / barWidth, 0))

    offset.value = barWidth * progress

    emits('progress-changing', progress)
  }
}
//PC端鼠标抬起
function onMouseUp() {
  //mouseup与click的冲突,冲突在200ms以内
  mouseup_click_debug.value = true
  setTimeout(function () {
    mouseup_click_debug.value = false;
  }, 200);

  const barWidth = progressBarRef.value.clientWidth - progressBtnWidth
  const progress = progressRef.value.clientWidth / barWidth
  document.onmousemove = null

  emits('progress-changed', progress)
}
//点击定位到哪个进度
function onClick(e) {
  if(mouseup_click_debug.value = true){
    return
  }else{
    const rect = progressBarRef.value.getBoundingClientRect()
  const offsetWidth = e.pageX - rect.left
  const barWidth = progressBarRef.value.clientWidth - progressBtnWidth
  const progress = offsetWidth / barWidth
  emits('progress-changed', progress)
  }
}

</script>

<style  scoped>
.progress-bar {
  height: 30px;
  width: 100%;
}

.bar-inner {
  position: relative;
  top: 13px;
  height: 4px;
  background: rgba(0, 0, 0, 0.3);
}

.progress {
  position: absolute;
  height: 100%;
  background: #0FA2FF;
}

.progress-btn-wrapper {
  position: absolute;
  left: -8px;
  top: -13px;
  width: 30px;
  height: 30px;
}

.progress-btn {
  position: relative;
  top: 7px;
  left: 7px;
  box-sizing: border-box;
  width: 16px;
  height: 16px;
  border: 3px solid #fff;
  border-radius: 50%;
  background: #0FA2FF;
}
</style>

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值