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>
关键改进点
- 移除CSS动画依赖:通过Vue响应式计算直接控制进度条的
transform: rotate()角度,完全摆脱CSS动画时间线的限制 - 实时进度计算:每次音频时间更新(包括跳转),
progressPercent会同步更新,进而触发旋转角度的重新计算,进度条立刻同步到对应位置 - 分阶段处理进度:根据进度是否超过50%,分别控制左右两侧进度条的旋转状态,完美实现环形进度效果
- 类型修正:将
duration属性改为Number类型,避免字符串转数字的潜在问题
内容的提问来源于stack exchange,提问作者AdRock
相关产品推荐
相关产品推荐

