h5音频标签模拟实现语音条(VUE3)

本文介绍了一种在Vue应用中,通过CSS隐藏原audio标签并用自定义div模拟语音条的实现方式,利用audioRef操作音频播放和暂停,并展示了如何获取音频时长以及添加播放动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:将原audio标签通过css隐藏,在通过css的div实现语音条样式,获取到audio的ref,操作audio的play、pause方法即可

效果图:

<template>

  <div style="display: none">

    <audio

      controls

      ref="audioRef"

      @loadedmetadata="handleLoadedMetadata"

      @ended="audioEnded"

    >

      <!-- <source :src="audioSrc" /> -->

      <source src="../../assets/aa.mp3" />

      您的浏览器不支持语音播放。

    </audio>

  </div>

  <div

    :style="{ width: audioWidth }"

    class="audio-detail-msg"

    @click="playAudio"

  >

    <div

      class="audio-style"

      :class="{

        'add-animation': isPlay,

      }"

    >

      <div class="small"></div>

      <div class="middle"></div>

      <div class="large"></div>

    </div>

    <div style="margin-left: 10px">{{ duration }}</div>

  </div>

</template>

<script lang="ts" setup>

import { ref, computed } from "vue";

// const props = defineProps<{

//   audioUrl: string,

// }>()

const audioRef = ref(null); // 音频组件ref

const isPlay = ref(false); //语音条播放效果

const duration = ref(null); //音频时长

//播放/停止音频

function playAudio() {

  if (isPlay.value) {

    audioRef?.value?.pause();

    isPlay.value = false;

  } else {

    // audioRef.value.src = audioUrl;

    audioRef?.value?.play();

    isPlay.value = true;

  }

}

//语音条播放结束

function audioEnded() {

  isPlay.value = false;

}

//获取音频时长

function handleLoadedMetadata() {

  if (audioRef.value) {

    // 音频时长可以通过 audioRef.value.duration 获取

    duration.value = audioRef.value.duration.toFixed(0);

  }

}

//动态计算语音条宽度

const audioWidth = computed(() => {

  return `${duration.value * 5 + 50}px`; // 将秒数乘以 5 得到宽度

});

</script>

<style lang="scss" scoped>

// 语音条

.audio-detail-msg {

  display: flex;

  align-items: center;

  cursor: pointer;

  padding: 0px 10px 0px 5px;

  background-color: #d7d7d7;

  border-radius: 2px;

  .audio-style {

    display: flex;

    align-items: center;

    height: 32px;

    border-radius: 4px;

    .small {

      border: 4px solid #4c4c4c;

      border-top-color: transparent;

      border-left-color: transparent;

      border-bottom-color: transparent;

    }

    .middle {

      width: 16px;

      height: 16px;

      margin-left: -11px;

      opacity: 1;

    }

    .large {

      width: 24px;

      height: 24px;

      margin-left: -19px;

      opacity: 1;

    }

    &>div {

      border: 2px solid #4c4c4c;

      border-top-color: transparent;

      border-left-color: transparent;

      border-bottom-color: transparent;

      border-radius: 50%;

      box-sizing: border-box;

    }

    &.add-animation {

      .middle {

        animation: show2 1.2s ease-in-out infinite;

      }

      .large {

        animation: show3 1.2s ease-in-out infinite;

      }

    }

  }

  .duration-seconds {

    font-size: 12px;

    margin: 0 8px;

  }
 

  // 语音播放动画

  @keyframes show2 {

    0% {

      opacity: 0;

    }

    10% {

      opacity: 1;

    }

    100% {

      opacity: 0;

    }

  }

  @keyframes show3 {

    0% {

      opacity: 0;

    }

    50% {

      opacity: 1;

    }

    60% {

      opacity: 0;

    }

    100% {

      opacity: 0;

    }

  }

}

</style>

下面附上代码截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值