Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
56 changes: 48 additions & 8 deletions src/components/Sing/ScoreSequencer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<sequencer-keys
class="sequencer-keys"
:offset="scrollY"
:black-key-width="30"
:black-key-width="28"
/>
<!-- シーケンサ -->
<div
Expand Down Expand Up @@ -182,6 +182,13 @@ import {
keyInfos,
getDoremiFromNoteNumber,
getNumOfMeasures,
ZOOM_X_MIN,
ZOOM_X_MAX,
ZOOM_X_STEP,
ZOOM_Y_MIN,
ZOOM_Y_MAX,
ZOOM_Y_STEP,
PREVIEW_SOUND_DURATION,
} from "@/helpers/singHelper";

export default defineComponent({
Expand All @@ -193,13 +200,6 @@ export default defineComponent({
SequencerPhraseIndicator,
},
setup() {
const ZOOM_X_MIN = 0.2;
const ZOOM_X_MAX = 1;
const ZOOM_X_STEP = 0.05;
const ZOOM_Y_MIN = 0.35;
const ZOOM_Y_MAX = 1;
const ZOOM_Y_STEP = 0.05;

enum DragMode {
NONE = "NONE",
MOVE = "MOVE",
Expand Down Expand Up @@ -334,6 +334,10 @@ export default defineComponent({
lyric,
},
});
store.dispatch("PLAY_PREVIEW_SOUND", {
noteNumber,
duration: PREVIEW_SOUND_DURATION,
});
};

// マウスダウン
Expand All @@ -359,6 +363,20 @@ export default defineComponent({
if (dragMode.value !== DragMode.NONE) {
cancelAnimationFrame(dragId.value);
dragMode.value = DragMode.NONE;

if (selectedNoteIds.value.length === 1) {
const selectedNoteId = selectedNoteIds.value[0];
const selectedNote = state.score.notes.find((value) => {
return value.id === selectedNoteId;
});
if (!selectedNote) {
throw new Error("selectedNote is undefined.");
}
store.dispatch("PLAY_PREVIEW_SOUND", {
noteNumber: selectedNote.noteNumber,
duration: PREVIEW_SOUND_DURATION,
});
}
return;
}
};
Expand Down Expand Up @@ -582,9 +600,11 @@ export default defineComponent({

// キーボードイベント
const handleNotesArrowUp = () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleNotesArrowUphandleNotesArrowDown、処理共通化できそうに感じました!!

let changedNoteNumber: number | undefined;
const newNotes = state.score.notes.map((note) => {
if (selectedNoteIds.value.includes(note.id)) {
const noteNumber = Math.min(note.noteNumber + 1, 127);
changedNoteNumber = noteNumber;
return {
...note,
noteNumber,
Expand All @@ -597,12 +617,23 @@ export default defineComponent({
return;
}
store.dispatch("REPLACE_ALL_NOTES", { notes: newNotes });
if (
changedNoteNumber !== undefined &&
selectedNoteIds.value.length === 1
) {
store.dispatch("PLAY_PREVIEW_SOUND", {
noteNumber: changedNoteNumber,
duration: PREVIEW_SOUND_DURATION,
});
}
};

const handleNotesArrowDown = () => {
let changedNoteNumber: number | undefined;
const newNotes = state.score.notes.map((note) => {
if (selectedNoteIds.value.includes(note.id)) {
const noteNumber = Math.max(note.noteNumber - 1, 0);
changedNoteNumber = noteNumber;
return {
...note,
noteNumber,
Expand All @@ -615,6 +646,15 @@ export default defineComponent({
return;
}
store.dispatch("REPLACE_ALL_NOTES", { notes: newNotes });
if (
changedNoteNumber !== undefined &&
selectedNoteIds.value.length === 1
) {
store.dispatch("PLAY_PREVIEW_SOUND", {
noteNumber: changedNoteNumber,
duration: PREVIEW_SOUND_DURATION,
});
}
};

const handleNotesArrowRight = () => {
Expand Down
133 changes: 91 additions & 42 deletions src/components/Sing/SequencerKeys.vue
Original file line number Diff line number Diff line change
@@ -1,45 +1,52 @@
<template>
<div ref="sequencerKeys" class="sequencer-keys">
<svg xmlns="http://www.w3.org/2000/svg" :width="width" :height="height">
<defs>
<symbol id="white-keys">
<g v-for="(whiteKeyInfo, index) in whiteKeyInfos" :key="index">
<rect
:x="whiteKeyRects[index].x - 0.5"
:y="whiteKeyRects[index].y + 0.5"
:width="whiteKeyRects[index].width"
:height="whiteKeyRects[index].height"
class="sequencer-keys-item-white"
:title="whiteKeyInfo.name"
/>
<text
v-if="whiteKeyInfo.pitch === 'C'"
font-size="10"
:x="blackKeyWidth + 2"
:y="whiteKeyRects[index].y + whiteKeyRects[index].height - 4"
class="sequencer-keys-item-pitchname"
>
{{ whiteKeyInfo.name }}
</text>
</g>
</symbol>
<symbol id="black-keys">
<rect
v-for="(blackKeyInfo, index) in blackKeyInfos"
:key="index"
:x="blackKeyRects[index].x - 0.5"
:y="blackKeyRects[index].y + 0.5"
:width="blackKeyRects[index].width"
:height="blackKeyRects[index].height"
rx="2"
ry="2"
class="sequencer-keys-item-black"
:title="blackKeyInfo.name"
/>
</symbol>
</defs>
<use href="#white-keys" :y="-offset" />
<use href="#black-keys" :y="-offset" />
<g
v-for="(whiteKeyInfo, index) in whiteKeyInfos"
:key="index"
@mousedown="onMouseDown(whiteKeyInfo.noteNumber)"
@mouseenter="onMouseEnter(whiteKeyInfo.noteNumber)"
>
<rect
:x="whiteKeyRects[index].x - 0.5"
:y="whiteKeyRects[index].y + 0.5 - offset"
:width="whiteKeyRects[index].width"
:height="whiteKeyRects[index].height"
:title="whiteKeyInfo.name"
:class="
noteNumberOfKeyBeingPressed === whiteKeyInfo.noteNumber
? 'white-key-being-pressed'
: 'white-key'
"
/>
<text
v-if="whiteKeyInfo.pitch === 'C'"
font-size="10"
:x="whiteKeyRects[index].x + whiteKeyRects[index].width - 18"
:y="whiteKeyRects[index].y + whiteKeyRects[index].height - 4 - offset"
class="pitchname"
>
{{ whiteKeyInfo.name }}
</text>
</g>
<rect
v-for="(blackKeyInfo, index) in blackKeyInfos"
:key="index"
:x="blackKeyRects[index].x - 0.5"
:y="blackKeyRects[index].y + 0.5 - offset"
:width="blackKeyRects[index].width"
:height="blackKeyRects[index].height"
rx="2"
ry="2"
:title="blackKeyInfo.name"
:class="
noteNumberOfKeyBeingPressed === blackKeyInfo.noteNumber
? 'black-key-being-pressed'
: 'black-key'
"
@mousedown="onMouseDown(blackKeyInfo.noteNumber)"
@mouseenter="onMouseEnter(blackKeyInfo.noteNumber)"
/>
</svg>
</div>
</template>
Expand Down Expand Up @@ -103,10 +110,37 @@ export default defineComponent({
};
});
});
const noteNumberOfKeyBeingPressed = ref<number | undefined>();

const sequencerKeys = ref<HTMLElement | null>(null);
let resizeObserver: ResizeObserver | undefined;

const onMouseDown = (noteNumber: number) => {
noteNumberOfKeyBeingPressed.value = noteNumber;
store.dispatch("PLAY_PREVIEW_SOUND", { noteNumber });
};

const onMouseUp = () => {
if (noteNumberOfKeyBeingPressed.value !== undefined) {
const noteNumber = noteNumberOfKeyBeingPressed.value;
noteNumberOfKeyBeingPressed.value = undefined;
store.dispatch("STOP_PREVIEW_SOUND", { noteNumber });
}
};

const onMouseEnter = (noteNumber: number) => {
if (
noteNumberOfKeyBeingPressed.value !== undefined &&
noteNumberOfKeyBeingPressed.value !== noteNumber
) {
store.dispatch("STOP_PREVIEW_SOUND", {
noteNumber: noteNumberOfKeyBeingPressed.value,
});
noteNumberOfKeyBeingPressed.value = noteNumber;
store.dispatch("PLAY_PREVIEW_SOUND", { noteNumber });
}
};

onMounted(() => {
const sequencerKeysElement = sequencerKeys.value;
if (!sequencerKeysElement) {
Expand All @@ -124,10 +158,13 @@ export default defineComponent({
}
});
resizeObserver.observe(sequencerKeysElement);

document.addEventListener("mouseup", onMouseUp);
});

onUnmounted(() => {
resizeObserver?.disconnect();
document.removeEventListener("mouseup", onMouseUp);
});

return {
Expand All @@ -141,6 +178,9 @@ export default defineComponent({
whiteKeyRects,
blackKeyRects,
sequencerKeys,
noteNumberOfKeyBeingPressed,
onMouseDown,
onMouseEnter,
};
},
});
Expand All @@ -157,16 +197,25 @@ export default defineComponent({
overflow: hidden;
}

.sequencer-keys-item-white {
.white-key {
fill: #fff;
stroke: #ccc;
}

.sequencer-keys-item-black {
.white-key-being-pressed {
fill: colors.$primary;
stroke: colors.$primary;
}

.black-key {
fill: #5a5a5a;
}

.sequencer-keys-item-pitchname {
.black-key-being-pressed {
fill: colors.$primary;
}

.pitchname {
fill: #555;
}
</style>
31 changes: 19 additions & 12 deletions src/components/Sing/SequencerNote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import {
getKeyBaseHeight,
tickToBaseX,
noteNumberToBaseY,
PREVIEW_SOUND_DURATION,
} from "@/helpers/singHelper";

export default defineComponent({
Expand Down Expand Up @@ -126,34 +127,40 @@ export default defineComponent({
}
};

const selectThisNote = () => {
const noteIds = [...state.selectedNoteIds, props.note.id];
store.dispatch("SET_SELECTED_NOTE_IDS", {
noteIds,
});
store.dispatch("PLAY_PREVIEW_SOUND", {
noteNumber: props.note.noteNumber,
duration: PREVIEW_SOUND_DURATION,
});
};

const handleKeydown = (event: KeyboardEvent) => {
emit("handleNotesKeydown", event);
};

const handleMouseDown = (event: MouseEvent) => {
if (!state.selectedNoteIds.includes(props.note.id)) {
const noteIds = [...state.selectedNoteIds, props.note.id];
store.dispatch("SET_SELECTED_NOTE_IDS", {
noteIds,
});
selectThisNote();
} else {
emit("handleDragMoveStart", event);
}
};

const handleDragRightStart = (event: MouseEvent) => {
const noteIds = [...state.selectedNoteIds, props.note.id];
store.dispatch("SET_SELECTED_NOTE_IDS", {
noteIds,
});
if (!state.selectedNoteIds.includes(props.note.id)) {
selectThisNote();
}
emit("handleDragRightStart", event);
};

const handleDragLeftStart = (event: MouseEvent) => {
const noteIds = [...state.selectedNoteIds, props.note.id];
store.dispatch("SET_SELECTED_NOTE_IDS", {
noteIds,
});
if (!state.selectedNoteIds.includes(props.note.id)) {
selectThisNote();
}
emit("handleDragLeftStart", event);
};

Expand Down
8 changes: 8 additions & 0 deletions src/helpers/singHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ export const DEFAULT_BEAT_TYPE = 4;
const BASE_X_PER_QUARTER_NOTE = 120;
const BASE_Y_PER_NOTE_NUMBER = 30;

export const ZOOM_X_MIN = 0.2;
export const ZOOM_X_MAX = 1;
export const ZOOM_X_STEP = 0.05;
export const ZOOM_Y_MIN = 0.35;
export const ZOOM_Y_MAX = 1;
export const ZOOM_Y_STEP = 0.05;
export const PREVIEW_SOUND_DURATION = 0.1;

export function noteNumberToFrequency(noteNumber: number) {
return 440 * 2 ** ((noteNumber - 69) / 12);
}
Expand Down
Loading