Update metronome.vue

This commit is contained in:
2026-05-27 18:27:25 +08:00
parent 0225e9f971
commit 3ebe3c58c8
+95 -9
View File
@@ -10,6 +10,26 @@
/> />
</view> </view>
<!-- ===== 音色选择 ===== -->
<view class="sound-selector">
<view
class="sound-option"
:class="{ active: currentSound === 'crisp' }"
@click="onSoundSelect('crisp')"
>
<text class="sound-icon"></text>
<text class="sound-label">清脆</text>
</view>
<view
class="sound-option"
:class="{ active: currentSound === 'wood' }"
@click="onSoundSelect('wood')"
>
<text class="sound-icon">🪵</text>
<text class="sound-label">木鱼</text>
</view>
</view>
<!-- ===== 推荐档位(3 1) ===== --> <!-- ===== 推荐档位(3 1) ===== -->
<view class="presets"> <view class="presets">
<view <view
@@ -79,25 +99,34 @@ interface LoopPreset {
} }
const LOOP_PRESETS: readonly LoopPreset[] = [ const LOOP_PRESETS: readonly LoopPreset[] = [
{ id: 'slow', bpm: 80, label: '慢走', desc: '热身 · 恢复' }, { id: 'slow', bpm: 110, label: '慢走', desc: '热身 · 恢复' },
{ id: 'normal', bpm: 110, label: '健走', desc: '日常 · 通勤' }, { id: 'normal', bpm: 130, label: '健走', desc: '日常 · 通勤' },
{ id: 'brisk', bpm: 130, label: '快走', desc: '提速 · 燃脂' }, { id: 'brisk', bpm: 150, label: '快走', desc: '提速 · 燃脂' },
] ]
const customExpanded = ref<boolean>(false) const customExpanded = ref<boolean>(false)
const currentLoop = ref<LoopId | null>('normal') const currentLoop = ref<LoopId | null>('normal')
const currentSound = ref<'crisp' | 'wood'>('crisp')
const walkerCanvasRef = ref<any>(null) const walkerCanvasRef = ref<any>(null)
/* click-wood.mp3 (CDN), 木鱼质感的敲击音 */ /* 节拍器音效配置 */
const CLICK_WOOD_URL = const SOUND_PRESETS = {
'https://gz-1349751149.cos.ap-guangzhou.myqcloud.com/uploads/file/20260526/202605261051282a0a94508.mp3' crisp: {
normal: 'https://gz-1349751149.cos.ap-guangzhou.myqcloud.com/uploads/file/20260527/202605271539371ebe13672.mp3',
accent: 'https://gz-1349751149.cos.ap-guangzhou.myqcloud.com/uploads/file/20260527/202605271539376ff628472.mp3',
},
wood: {
normal: 'https://gz-1349751149.cos.ap-guangzhou.myqcloud.com/uploads/file/20260526/202605261051282a0a94508.mp3',
accent: 'https://gz-1349751149.cos.ap-guangzhou.myqcloud.com/uploads/file/20260526/202605261051282a0a94508.mp3',
},
}
// 统一采用高精度引擎,彻底抛弃卡顿的后台播放引擎 // 统一采用高精度引擎,彻底抛弃卡顿的后台播放引擎
const fg = useMetronome({ const fg = useMetronome({
initialBpm: 110, initialBpm: 130,
accentEvery: 2, accentEvery: 2,
clickSrc: CLICK_WOOD_URL, clickSrc: SOUND_PRESETS.crisp.normal,
accentSrc: CLICK_WOOD_URL, accentSrc: SOUND_PRESETS.crisp.accent,
poolSize: 4, poolSize: 4,
// 【完美音画同步核心】 // 【完美音画同步核心】
onBeat: (index, isAccent) => { onBeat: (index, isAccent) => {
@@ -163,6 +192,12 @@ const onAccentSelect = (n: number) => {
fg.setAccentEvery(n) fg.setAccentEvery(n)
} }
const onSoundSelect = (sound: 'crisp' | 'wood') => {
currentSound.value = sound
const preset = SOUND_PRESETS[sound]
fg.updateAudioSrc(preset.normal, preset.accent)
}
const rootStyle = computed(() => ({ const rootStyle = computed(() => ({
'--beat-duration': `${intervalMs.value}ms`, '--beat-duration': `${intervalMs.value}ms`,
})) }))
@@ -232,6 +267,57 @@ $shadow-sm: 0 4rpx 12rpx rgba(15, 23, 42, 0.04);
position: relative; position: relative;
} }
/* ============================================================
* 音色选择器
* ============================================================ */
.sound-selector {
width: 100%;
display: flex;
gap: 14rpx;
margin-bottom: 20rpx;
}
.sound-option {
flex: 1;
background: $card-bg;
border: 2rpx solid $card-border;
border-radius: $radius-card;
padding: 20rpx 16rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 10rpx;
box-shadow: $shadow-sm;
transition: all 0.18s;
.sound-icon {
font-size: 32rpx;
}
.sound-label {
font-size: 26rpx;
font-weight: 600;
color: $text-2;
letter-spacing: 1rpx;
}
&:active {
transform: scale(0.97);
}
&.active {
background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
border-color: $brand;
box-shadow:
0 8rpx 20rpx rgba(16, 185, 129, 0.18),
inset 0 0 0 2rpx rgba(16, 185, 129, 0.4);
.sound-label {
color: $brand-deep;
}
}
}
/* ============================================================ /* ============================================================
* 三档位推荐 * 三档位推荐
* ============================================================ */ * ============================================================ */