Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
dbe4054
ソング:カーソルをシーケンサーの端に持っていったときにスクロールする機能を追加【暫定】(#2319)
terapotan Mar 2, 2025
bcf924d
Merge remote-tracking branch 'origin/main' into AddScrollFunction
terapotan Mar 3, 2025
f4f1389
ステートマシン実装に伴う実装の変更
terapotan Mar 3, 2025
798790b
上下左右対応、マウスを動かさなくても自動スクロールするように修正
terapotan Mar 3, 2025
66dc90d
指摘事項修正
terapotan Mar 4, 2025
9150c9f
autoScrollableModeを削除
terapotan Mar 4, 2025
a5c1b74
指摘事項修正
terapotan Mar 6, 2025
365e968
sequencerBodyがundefinedのときthorw exceptionする対応について、漏れがあったので修正
terapotan Mar 6, 2025
2c3025b
ノート追加、ノートリサイズ時でも自動スクロールが発動するように修正、他指摘事項修正
terapotan Mar 8, 2025
0195f3d
Merge branch 'main' into AddScrollFunction
Hiroshiba Mar 8, 2025
675431c
端から離れている量によって、スクロールスピードが変化するように修正
terapotan Mar 12, 2025
7235e57
指摘事項修正
terapotan Mar 20, 2025
f851a9c
Merge branch 'AddScrollFunction' of https://github.com/terapotan/voic…
terapotan Mar 20, 2025
62109e1
スクロール量を計算する処理を変更、コードを整理
sigprogramming Mar 22, 2025
6f73039
修正
sigprogramming Mar 22, 2025
330cfd5
isMagnitudeZeroを削除
sigprogramming Mar 22, 2025
5f0ef78
リファクタリング
sigprogramming Mar 22, 2025
1463b46
自動スクロール処理をコンポーザブル化
sigprogramming Mar 22, 2025
d2c44c2
修正
sigprogramming Mar 22, 2025
b1749d7
nullに統一
sigprogramming Mar 22, 2025
11d2a69
mountedをwatchするようにした
sigprogramming Mar 23, 2025
f05628c
マウント前に自動スクロールを有効にしても動くように
sigprogramming Mar 23, 2025
fa80ebf
Merge branch 'main' into AddScrollFunction
Hiroshiba Mar 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 79 additions & 1 deletion src/components/Sing/ScoreSequencer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ const {
previewPitchEdit,
cursorState,
guideLineTicks,
enableAutoScrollDuringDrag,
} = useSequencerStateMachine(store);

const nowPreviewing = computed(() => previewMode.value !== "IDLE");
Expand Down Expand Up @@ -599,15 +600,92 @@ const onMouseDown = (event: MouseEvent) => {
}
};

let autoScrollDuringDragAnimationId: number | undefined = undefined;
let previousTimeStamp: number | undefined = undefined;
const scrollSpeedPerMS = 0.2; // 1msあたりの自動スクロールスピード
let scrollXMultiplier: number = 0; //右方向+1,左方向-1
let scrollYMultiplier: number = 0; //上方向-1,下方向+1

const autoScrollAnimation = (timestamp: number) => {
if (sequencerBody.value == undefined) {
throw new Error("sequencer.value is undefined.");
}

if (previousTimeStamp == undefined) {
previousTimeStamp = timestamp;
}
const elapsed = timestamp - previousTimeStamp;
sequencerBody.value.scrollBy({
top: Math.floor(scrollYMultiplier * scrollSpeedPerMS * elapsed),
left: Math.floor(scrollXMultiplier * scrollSpeedPerMS * elapsed),
behavior: "auto",
});

previousTimeStamp = timestamp;
autoScrollDuringDragAnimationId = requestAnimationFrame(autoScrollAnimation);
};

const onMouseMove = (event: MouseEvent) => {
if (sequencerBody.value == undefined) {
throw new Error("sequencer.value is undefined.");
}
const cursorPos = getCursorPosOnSequencer(event);

// カーソルがノートを持っていて、カーソルがシーケンサーの範囲外に出たときに
// 自動スクロールする処理を以下で行う
if (enableAutoScrollDuringDrag.value) {
const threshold = 15;

if (cursorPos.x > sequencerBody.value.clientWidth - threshold) {
// 右端
scrollXMultiplier = 1;
scrollYMultiplier = 0;
} else if (cursorPos.x < threshold) {
// 左端
scrollXMultiplier = -1;
scrollYMultiplier = 0;
} else if (cursorPos.y < threshold) {
// 上端
scrollXMultiplier = 0;
scrollYMultiplier = -1;
} else if (cursorPos.y > sequencerBody.value.clientHeight - threshold) {
// 下端
scrollXMultiplier = 0;
scrollYMultiplier = 1;
} else {
// マウスカーソルが上下左右の端にないとき
scrollXMultiplier = 0;
scrollYMultiplier = 0;
}
}
stateMachineProcess({
type: "mouseEvent",
targetArea: "Window",
mouseEvent: event,
cursorPos: getCursorPosOnSequencer(event),
cursorPos: cursorPos,
});
};

watch(enableAutoScrollDuringDrag, (newFlag, oldFlag) => {
// previewModeを抜けるとき
// 自動スクロールを停止する
if (!newFlag) {
if (autoScrollDuringDragAnimationId != undefined) {
cancelAnimationFrame(autoScrollDuringDragAnimationId);
autoScrollDuringDragAnimationId = undefined;
}
scrollXMultiplier = 0;
scrollYMultiplier = 0;
} else {
// previewModeに入ったとき
// 常にアニメーションループをスタートする
// 実際に動かさなければならない場面になったら
// scrollXMultiplier,scrollYMultiplierの値を0以外にセットする
autoScrollDuringDragAnimationId =
requestAnimationFrame(autoScrollAnimation);
}
});

const onMouseUp = (event: MouseEvent) => {
stateMachineProcess({
type: "mouseEvent",
Expand Down
4 changes: 4 additions & 0 deletions src/composables/useSequencerStateMachine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const useSequencerStateMachine = (store: PartialStore) => {
previewPitchEdit: ref(undefined),
cursorState: ref("UNSET"),
guideLineTicks: ref(0),
enableAutoScrollDuringDrag: ref(false),
};

const idleStateId = computed((): IdleStateId => {
Expand Down Expand Up @@ -88,5 +89,8 @@ export const useSequencerStateMachine = (store: PartialStore) => {
previewPitchEdit: computed(() => refs.previewPitchEdit.value),
cursorState: computed(() => refs.cursorState.value),
guideLineTicks: computed(() => refs.guideLineTicks.value),
enableAutoScrollDuringDrag: computed(
() => refs.enableAutoScrollDuringDrag.value,
),
};
};
1 change: 1 addition & 0 deletions src/sing/sequencerStateMachine/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export type Refs = {
>;
readonly cursorState: Ref<CursorState>;
readonly guideLineTicks: Ref<number>;
enableAutoScrollDuringDrag: Ref<boolean>;
};

export type PartialStore = {
Expand Down
2 changes: 2 additions & 0 deletions src/sing/sequencerStateMachine/states/moveNoteState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export class MoveNoteState
}

onEnter(context: Context) {
context.enableAutoScrollDuringDrag.value = true;
const guideLineTicks = getGuideLineTicks(this.cursorPosAtStart, context);
const targetNotesArray = context.notesInSelectedTrack.value.filter(
(value) => this.targetNoteIds.has(value.id),
Expand Down Expand Up @@ -124,6 +125,7 @@ export class MoveNoteState
}

onExit(context: Context) {
context.enableAutoScrollDuringDrag.value = false;
if (this.innerContext == undefined) {
throw new Error("innerContext is undefined.");
}
Expand Down
Loading