You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VueJS中CSS环形音频进度条跳转后无法更新的问题求助

问题分析与解决方案

你的核心问题在于依赖CSS动画驱动进度条,CSS动画的时间线和音频播放的时间线在跳转后无法自动对齐,animation-range不仅浏览器支持有限,也不适用于这种需要实时同步动态位置的场景。

下面是重构后的实现方案,通过响应式计算旋转角度替代CSS动画,确保音频跳转时进度条实时同步:

修改后的完整代码

模板部分

<template>
  <div ref="mainCover" id="main_cover" @click="onClick">
    <div class="progress blue">
      <span class="progress-left">
          <span class="progress-bar" :style="{ transform: `rotate(${leftRotate}deg)` }"></span>
      </span>
      <span class="progress-right">
          <span class="progress-bar" :style="{ transform: `rotate(${rightRotate}deg)` }"></span>
      </span>
      <div class="progress-value">{{ Math.round(progressPercent) }}%</div>
    </div>
  </div>
</template>

脚本部分

<script setup>
import { defineProps, ref, computed } from 'vue'

const { duration } = defineProps({
  duration: {
    type: Number, // 改为Number类型更合理,避免类型转换
    required: true,
  },
})

let isPlaying = ref(false)
let currentTime = ref(0)

eventBus.on('playing', () => {
  isPlaying.value = true
})

eventBus.on('paused', () => {
  isPlaying.value = false
})

eventBus.on('timeupdate', (time) => {
  currentTime.value = time
})

// 计算当前进度百分比
const progressPercent = computed(() => {
  if (!duration) return 0
  return (currentTime.value / duration) * 100
})

// 计算左右进度条的旋转角度
const leftRotate = computed(() => {
  const percent = progressPercent.value
  return percent <= 50 ? percent * 3.6 : 180 + (percent - 50) * 3.6
})

const rightRotate = computed(() => {
  const percent = progressPercent.value
  return percent <= 50 ? 0 : 180
})

const mainCover = ref()

// 点击切换播放/暂停
const onClick = () => {
  if (isPlaying.value) {
    eventBus.emit('pause')
  } else {
    eventBus.emit('play')
  }
}
</script>

样式部分

<style lang="css" scoped>
.progress{
    width: 150px;
    height: 150px;
    line-height: 150px;
    background: none;
    margin: 0 auto;
    box-shadow: none;
    position: relative;
}
.progress:after{
    content: "";
    width: 100%;
    height: 100%;
    border-radius: 50%;
    border: 5px solid #f2f5f5;
    position: absolute;
    top: 0;
    left: 0;
}
.progress > span{
    width: 50%;
    height: 100%;
    overflow: hidden;
    position: absolute;
    top: 0;
    z-index: 1;
}
.progress .progress-left{
    left: 0;
}
.progress .progress-bar{
    width: 100%;
    height: 100%;
    background: none;
    border-width: 5px;
    border-style: solid;
    position: absolute;
    top: 0;
    transition: transform 0.1s ease; /* 增加平滑过渡 */
}
.progress .progress-left .progress-bar{
    left: 100%;
    border-top-right-radius: 80px;
    border-bottom-right-radius: 80px;
    border-left: 0;
    transform-origin: center left;
}
.progress .progress-right{
    right: 0;
}
.progress .progress-right .progress-bar{
    left: -100%;
    border-top-left-radius: 80px;
    border-bottom-left-radius: 80px;
    border-right: 0;
    transform-origin: center right;
}
.progress .progress-value{
    width: 100%;
    height: 100%;
    font-size: 24px;
    color: rgb(250, 245, 245);
    text-align: center;
    position: absolute;
}
.progress.blue .progress-bar{
    border-color: #26abfd;
}
</style>

关键改进点

  1. 移除CSS动画依赖:通过Vue响应式计算直接控制进度条的transform: rotate()角度,完全摆脱CSS动画时间线的限制
  2. 实时进度计算:每次音频时间更新(包括跳转),progressPercent会同步更新,进而触发旋转角度的重新计算,进度条立刻同步到对应位置
  3. 分阶段处理进度:根据进度是否超过50%,分别控制左右两侧进度条的旋转状态,完美实现环形进度效果
  4. 类型修正:将duration属性改为Number类型,避免字符串转数字的潜在问题

内容的提问来源于stack exchange,提问作者AdRock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 12:40:56