151 lines
5.7 KiB
JavaScript
151 lines
5.7 KiB
JavaScript
"use strict";
|
|
const common_vendor = require("../../common/vendor.js");
|
|
const training_hooks_useMetronome = require("../hooks/useMetronome.js");
|
|
if (!Math) {
|
|
WalkerCanvas();
|
|
}
|
|
const WalkerCanvas = () => "./components/walker-canvas.js";
|
|
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
|
|
__name: "metronome",
|
|
setup(__props) {
|
|
const LOOP_PRESETS = [
|
|
{ id: "slow", bpm: 110, label: "慢走", desc: "热身 · 恢复" },
|
|
{ id: "normal", bpm: 130, label: "健走", desc: "日常 · 通勤" },
|
|
{ id: "brisk", bpm: 150, label: "快走", desc: "提速 · 燃脂" }
|
|
];
|
|
const customExpanded = common_vendor.ref(false);
|
|
const currentLoop = common_vendor.ref("normal");
|
|
const currentSound = common_vendor.ref("crisp");
|
|
const walkerCanvasRef = common_vendor.ref(null);
|
|
const SOUND_PRESETS = {
|
|
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 = training_hooks_useMetronome.useMetronome({
|
|
initialBpm: 130,
|
|
accentEvery: 2,
|
|
clickSrc: SOUND_PRESETS.crisp.normal,
|
|
accentSrc: SOUND_PRESETS.crisp.accent,
|
|
poolSize: 4,
|
|
// 【完美音画同步核心】
|
|
onBeat: (index, isAccent) => {
|
|
if (walkerCanvasRef.value && walkerCanvasRef.value.triggerBeat) {
|
|
walkerCanvasRef.value.triggerBeat();
|
|
}
|
|
}
|
|
});
|
|
const isPlaying = common_vendor.computed(() => fg.isPlaying.value);
|
|
const currentBpm = common_vendor.computed(() => fg.bpm.value);
|
|
const customAccent = common_vendor.computed(() => fg.accentEvery.value);
|
|
const intervalMs = common_vendor.computed(() => 6e4 / fg.bpm.value);
|
|
const onCenterTap = () => {
|
|
if (fg.isPlaying.value) {
|
|
fg.stop();
|
|
common_vendor.index.setKeepScreenOn({ keepScreenOn: false });
|
|
} else {
|
|
fg.start();
|
|
common_vendor.index.setKeepScreenOn({ keepScreenOn: true });
|
|
}
|
|
};
|
|
const onPresetTap = (id) => {
|
|
const preset = LOOP_PRESETS.find((p) => p.id === id);
|
|
if (!preset)
|
|
return;
|
|
currentLoop.value = id;
|
|
fg.setBpm(preset.bpm);
|
|
if (!fg.isPlaying.value) {
|
|
fg.start();
|
|
common_vendor.index.setKeepScreenOn({ keepScreenOn: true });
|
|
}
|
|
};
|
|
const onToggleCustom = () => {
|
|
customExpanded.value = !customExpanded.value;
|
|
if (customExpanded.value) {
|
|
fg.preload();
|
|
} else {
|
|
const matched = LOOP_PRESETS.find((p) => p.bpm === fg.bpm.value);
|
|
currentLoop.value = matched ? matched.id : null;
|
|
}
|
|
};
|
|
const onBpmDelta = (delta) => {
|
|
fg.setBpm(fg.bpm.value + delta);
|
|
currentLoop.value = null;
|
|
};
|
|
const onAccentSelect = (n) => {
|
|
fg.setAccentEvery(n);
|
|
};
|
|
const onSoundSelect = (sound) => {
|
|
currentSound.value = sound;
|
|
const preset = SOUND_PRESETS[sound];
|
|
fg.updateAudioSrc(preset.normal, preset.accent);
|
|
};
|
|
const rootStyle = common_vendor.computed(() => ({
|
|
"--beat-duration": `${intervalMs.value}ms`
|
|
}));
|
|
common_vendor.onShow(() => {
|
|
fg.preload();
|
|
});
|
|
function cleanupMetronome() {
|
|
fg.stop();
|
|
common_vendor.index.setKeepScreenOn({ keepScreenOn: false });
|
|
}
|
|
common_vendor.onHide(cleanupMetronome);
|
|
common_vendor.onUnload(cleanupMetronome);
|
|
common_vendor.onUnmounted(cleanupMetronome);
|
|
return (_ctx, _cache) => {
|
|
return common_vendor.e({
|
|
a: common_vendor.sr(walkerCanvasRef, "a75aa31b-0", {
|
|
"k": "walkerCanvasRef"
|
|
}),
|
|
b: common_vendor.o(onCenterTap, "0f"),
|
|
c: common_vendor.p({
|
|
bpm: currentBpm.value,
|
|
["is-playing"]: isPlaying.value
|
|
}),
|
|
d: currentSound.value === "crisp" ? 1 : "",
|
|
e: common_vendor.o(($event) => onSoundSelect("crisp"), "8c"),
|
|
f: currentSound.value === "wood" ? 1 : "",
|
|
g: common_vendor.o(($event) => onSoundSelect("wood"), "43"),
|
|
h: common_vendor.f(LOOP_PRESETS, (p, k0, i0) => {
|
|
return {
|
|
a: common_vendor.t(p.label),
|
|
b: common_vendor.t(p.bpm),
|
|
c: common_vendor.t(p.desc),
|
|
d: p.id,
|
|
e: currentLoop.value === p.id ? 1 : "",
|
|
f: common_vendor.o(($event) => onPresetTap(p.id), p.id)
|
|
};
|
|
}),
|
|
i: common_vendor.t(customExpanded.value ? "✕ 收起自定义" : "⚙ 自定义节奏"),
|
|
j: common_vendor.o(onToggleCustom, "29"),
|
|
k: customExpanded.value
|
|
}, customExpanded.value ? {
|
|
l: common_vendor.o(($event) => onBpmDelta(-5), "71"),
|
|
m: common_vendor.o(($event) => onBpmDelta(-1), "5b"),
|
|
n: common_vendor.t(currentBpm.value),
|
|
o: common_vendor.o(($event) => onBpmDelta(1), "90"),
|
|
p: common_vendor.o(($event) => onBpmDelta(5), "b0"),
|
|
q: common_vendor.f([2, 3, 4], (n, k0, i0) => {
|
|
return {
|
|
a: common_vendor.t(n),
|
|
b: n,
|
|
c: customAccent.value === n ? 1 : "",
|
|
d: common_vendor.o(($event) => onAccentSelect(n), n)
|
|
};
|
|
})
|
|
} : {}, {
|
|
r: common_vendor.s(rootStyle.value)
|
|
});
|
|
};
|
|
}
|
|
});
|
|
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-a75aa31b"]]);
|
|
wx.createPage(MiniProgramPage);
|
|
//# sourceMappingURL=../../../.sourcemap/mp-weixin/training/pages/metronome.js.map
|