Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: 再生中のアクセント句の見た目を強調する処理を改善 #1526

Merged
42 changes: 26 additions & 16 deletions src/components/AudioDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -575,30 +575,40 @@ const scrollToActivePoint = () => {
};

// NodeJS.Timeout型が直接指定できないので、typeofとReturnTypeで取ってきている
thiramisu marked this conversation as resolved.
Show resolved Hide resolved
let focusInterval: ReturnType<typeof setInterval> | undefined;
let requestId: number | undefined;
watch(nowPlaying, async (newState) => {
if (newState) {
const accentPhraseOffsets = await store.dispatch("GET_AUDIO_PLAY_OFFSETS", {
audioKey: props.activeAudioKey,
});
// 現在再生されているaudio elementの再生時刻を0.01秒毎に取得(監視)し、
// 現在再生されているaudio elementの再生時刻を描画毎に取得(監視)し、
// それに合わせてフォーカスするアクセント句を変えていく
focusInterval = setInterval(() => {
const focusAccentPhrase = () => {
const currentTime = store.getters.ACTIVE_AUDIO_ELEM_CURRENT_TIME;
for (let i = 1; i < accentPhraseOffsets.length; i++) {
if (
currentTime !== undefined &&
accentPhraseOffsets[i - 1] <= currentTime &&
currentTime < accentPhraseOffsets[i]
) {
activePoint.value = i - 1;
scrollToActivePoint();
}
if (currentTime === undefined) {
throw new Error("currentTime === undefined)");
}
const playingAccentPhraseIndex =
accentPhraseOffsets.findIndex(
(currentOffset) => currentTime < currentOffset
) - 1;
if (playingAccentPhraseIndex === -1) {
// accentPhraseOffsets[0] は必ず 0 なので到達しないはず
throw new Error("playingAccentPhraseIndex === -1");
}
if (playingAccentPhraseIndex === -2) {
// データと音声ファイルの長さに誤差があるため許容
// see https://github.com/VOICEVOX/voicevox/issues/785
return;
}
}, 10);
} else if (focusInterval !== undefined) {
clearInterval(focusInterval);
focusInterval = undefined;
activePoint.value = playingAccentPhraseIndex;
scrollToActivePoint();
requestId = window.requestAnimationFrame(focusAccentPhrase);
};
requestId = window.requestAnimationFrame(focusAccentPhrase);
} else if (requestId !== undefined) {
window.cancelAnimationFrame(requestId);
requestId = undefined;
// startPointがundefinedの場合、一旦最初のアクセント句までスクロール、その後activePointの選択を解除(undefinedに)する
activePoint.value = startPoint.value ?? 0;
scrollToActivePoint();
Expand Down