feat: 语音输入交互完善

This commit is contained in:
duanshuwen
2025-08-10 19:40:47 +08:00
parent 5b1566fc33
commit 9c7063196c
6 changed files with 287 additions and 474 deletions

View File

@@ -0,0 +1,129 @@
<template>
<view class="recording-wave-btn">
<view class="audio-visualizer">
<view
v-for="(bar, index) in audioBars"
:key="index"
class="audio-bar"
:style="{
height: bar.height + 'px',
transition: 'height 0.1s ease-out',
}"
></view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
const animationTimer = ref(null);
const isAnimating = ref(false);
// 音频条数据
const audioBars = ref([]);
const BAR_COUNT = 30;
// 初始化音频条
const initAudioBars = () => {
audioBars.value = [];
for (let i = 0; i < BAR_COUNT; i++) {
audioBars.value.push({
height: 4 + Math.random() * 8,
});
}
};
// 更新音频条动画
const updateAudioBars = () => {
if (!isAnimating.value) return;
// 使用 for 循环随机修改每个音频条的高度
for (let i = 0; i < audioBars.value.length; i++) {
const bar = audioBars.value[i];
// 生成随机高度值
const minHeight = 4;
const maxHeight = 20;
const randomHeight = minHeight + Math.random() * (maxHeight - minHeight);
// 添加一些变化幅度,让高度变化更自然
const variation = (Math.random() - 0.5) * 10;
bar.height = Math.max(
minHeight,
Math.min(maxHeight, randomHeight + variation)
);
}
};
// 开始动画
const startAnimation = () => {
if (!isAnimating.value) {
isAnimating.value = true;
const animate = () => {
if (isAnimating.value) {
updateAudioBars();
animationTimer.value = setTimeout(animate, 200); // 每200ms更新一次模仿人类说话语速
}
};
animate();
}
};
// 停止动画
const stopAnimation = () => {
isAnimating.value = false;
if (animationTimer.value) {
clearTimeout(animationTimer.value);
animationTimer.value = null;
}
};
// 组件挂载时初始化并自动开始动画
onMounted(() => {
initAudioBars();
startAnimation();
});
// 组件卸载时停止动画
onUnmounted(() => {
stopAnimation();
});
// 暴露方法给父组件
defineExpose({
startAnimation,
stopAnimation,
});
</script>
<style scoped lang="scss">
.recording-wave-btn {
box-shadow: 0px 0px 20px 0px rgba(52, 25, 204, 0.05);
margin: 0 12px;
margin-bottom: 8px;
display: flex;
justify-content: center;
align-items: center;
background-color: #00a6ff;
height: 44px;
border-radius: 50px;
}
.audio-visualizer {
display: flex;
align-items: center;
justify-content: center;
height: 20px;
gap: 2px;
}
.audio-bar {
width: 2px;
height: 4px;
border-radius: 2px;
background-color: #fff;
}
</style>