diff --git a/src/components/Sing/SequencerNote.vue b/src/components/Sing/SequencerNote.vue
index a54e535f4e..5e29c6d8e4 100644
--- a/src/components/Sing/SequencerNote.vue
+++ b/src/components/Sing/SequencerNote.vue
@@ -3,7 +3,8 @@
class="note"
:class="{
selected: noteState === 'SELECTED',
- overlapping: noteState === 'OVERLAPPING',
+ overlapping: hasOverlappingError,
+ 'invalid-phrase': hasPhraseError,
'below-pitch': showPitch,
}"
:style="{
@@ -35,6 +36,26 @@
@keydown.stop="onLyricInputKeyDown"
@blur="onLyricInputBlur"
/>
+
+ ノートが重なっています
+
+
+ フレーズが生成できません。歌詞は日本語1文字までです。
+
@@ -50,7 +71,12 @@ import {
import ContextMenu from "@/components/Menu/ContextMenu.vue";
import { MenuItemButton } from "@/components/Menu/type";
-type NoteState = "NORMAL" | "SELECTED" | "OVERLAPPING";
+type NoteState =
+ | "NORMAL"
+ | "SELECTED"
+ | "RESIZING_LEFT"
+ | "RESIZING_RIGHT"
+ | "MOVING";
const vFocus = {
mounted(el: HTMLInputElement) {
@@ -102,11 +128,27 @@ const noteState = computed((): NoteState => {
if (props.isSelected) {
return "SELECTED";
}
- if (state.overlappingNoteIds.has(props.note.id)) {
- return "OVERLAPPING";
- }
return "NORMAL";
});
+
+// ノートの重なりエラー
+const hasOverlappingError = computed(() => {
+ return state.overlappingNoteIds.has(props.note.id);
+});
+
+// フレーズ生成エラー
+const hasPhraseError = computed(() => {
+ const phrases = state.phrases;
+ return Array.from(phrases.values()).some((phrase) => {
+ if (phrase.state !== "COULD_NOT_RENDER") {
+ return false;
+ }
+ if (phrase.notes.some((note) => note.id === props.note.id)) {
+ return true;
+ }
+ });
+});
+
const lyric = computed({
get() {
return props.note.lyric;
@@ -209,19 +251,32 @@ const onLyricInputBlur = () => {
&.selected {
// 色は仮
.note-bar {
- background-color: hsl(33, 100%, 50%);
+ background-color: hsl(130, 35%, 90%);
+ border: 2px solid colors.$primary;
}
&.below-pitch {
.note-bar {
- background-color: rgba(hsl(33, 100%, 50%), 0.18);
+ background-color: rgba(hsl(130, 100%, 50%), 0.18);
}
}
}
- &.overlapping {
+ &.overlapping,
+ &.invalid-phrase {
.note-bar {
- background-color: hsl(130, 35%, 85%);
+ background-color: rgba(colors.$warning-rgb, 0.5);
+ }
+
+ .note-lyric {
+ opacity: 0.6;
+ }
+
+ &.selected {
+ .note-bar {
+ background-color: rgba(colors.$warning-rgb, 0.5);
+ border-color: colors.$warning;
+ }
}
}
}
@@ -274,8 +329,10 @@ const onLyricInputBlur = () => {
position: absolute;
bottom: 0;
font-weight: 700;
- width: 2rem;
- border: 1px solid hsl(33, 100%, 73%);
+ min-width: 3rem;
+ max-width: 6rem;
+ border: 0;
+ outline: 2px solid colors.$primary;
border-radius: 0.25rem;
}