Skip to content

Commit

Permalink
Noteの状態をリファクタリング
Browse files Browse the repository at this point in the history
  • Loading branch information
romot-co committed Sep 17, 2024
1 parent 02b761c commit caeb71c
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 65 deletions.
10 changes: 1 addition & 9 deletions src/components/Sing/ScoreSequencer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ import {
import ContextMenu, {
ContextMenuItemData,
} from "@/components/Menu/ContextMenu.vue";
import { NoteId } from "@/type/preload";
import { NoteId, PreviewMode } from "@/type/preload";
import { useStore } from "@/store";
import { Note, SequencerEditTarget } from "@/store/type";
import {
Expand Down Expand Up @@ -222,14 +222,6 @@ import { useLyricInput } from "@/composables/useLyricInput";
import { ExhaustiveError } from "@/type/utility";
import { uuid4 } from "@/helpers/random";
type PreviewMode =
| "ADD_NOTE"
| "MOVE_NOTE"
| "RESIZE_NOTE_RIGHT"
| "RESIZE_NOTE_LEFT"
| "DRAW_PITCH"
| "ERASE_PITCH";
// 直接イベントが来ているかどうか
const isSelfEventTarget = (event: UIEvent) => {
return event.target === event.currentTarget;
Expand Down
70 changes: 35 additions & 35 deletions src/components/Sing/SequencerNote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import { computed, ref } from "vue";
import { useStore } from "@/store";
import { Note } from "@/store/type";
import { PreviewMode } from "@/type/preload";
import {
getKeyBaseHeight,
tickToBaseX,
Expand All @@ -58,13 +59,7 @@ const props = defineProps<{
/** どれかのノートがプレビュー中 */
nowPreviewing: boolean;
/** プレビューモード */
previewMode:
| "ADD_NOTE"
| "MOVE_NOTE"
| "RESIZE_NOTE_RIGHT"
| "RESIZE_NOTE_LEFT"
| "DRAW_PITCH"
| "ERASE_PITCH";
previewMode: PreviewMode;
/** このノートが選択中か */
isSelected: boolean;
/** このノートがプレビュー中か */
Expand Down Expand Up @@ -102,12 +97,6 @@ const width = computed(() => {
const noteEndBaseX = tickToBaseX(noteEndTicks, tpqn.value);
return (noteEndBaseX - noteStartBaseX) * zoomX.value;
});
const resizingRight = computed(() => {
return props.isPreview && props.previewMode === "RESIZE_NOTE_RIGHT";
});
const resizingLeft = computed(() => {
return props.isPreview && props.previewMode === "RESIZE_NOTE_LEFT";
});
// 歌詞のフォントサイズをズームにあわせて調整する
// 最小12px, 最大16px, ノートの高さは越えない
const lyricFontSize = computed(() => {
Expand Down Expand Up @@ -218,6 +207,7 @@ const onLeftEdgeMouseDown = (event: MouseEvent) => {
emit("leftEdgeMousedown", event);
};
// ノートの状態に応じたCSSクラス
const noteClasses = computed(() => ({
edit: editTargetIsNote.value,
"below-pitch": editTargetIsPitch.value,
Expand All @@ -227,23 +217,26 @@ const noteClasses = computed(() => ({
error: hasOverlappingError.value || hasPhraseError.value,
overlapping: hasOverlappingError.value,
"invalid-phrase": hasPhraseError.value,
resizing: resizingRight.value || resizingLeft.value,
"resizing-right": resizingRight.value,
"resizing-left": resizingLeft.value,
move: props.previewMode === "MOVE_NOTE" && props.isPreview,
"resize-note-right":
props.previewMode === "RESIZE_NOTE_RIGHT" && props.isPreview,
"resize-note-left":
props.previewMode === "RESIZE_NOTE_LEFT" && props.isPreview,
"move-note": props.previewMode === "MOVE_NOTE" && props.isPreview,
}));
// ノートのスタイル
const noteStyle = computed(() => ({
width: `${width.value}px`,
height: `${height.value}px`,
transform: `translate3d(${positionX.value}px,${positionY.value}px,0)`,
transform: `translate3d(${positionX.value}px,${positionY.value}px,0)`, // ノートの位置
}));
// ノートの歌詞のスタイル。位置およびサイズを調整
const lyricStyle = computed(() => ({
fontSize: `${lyricFontSize.value}px`,
left: `${lyricLeftPosition.value}px`,
lineHeight: `${height.value}px`,
transform: `translate3d(0,${height.value}px,0)`,
transform: `translate3d(0,${height.value}px,0)`, // ノートに対して歌詞を縦中央に配置
}));
</script>

Expand All @@ -268,6 +261,7 @@ const lyricStyle = computed(() => ({
top: 0;
left: 0;
// ノートバー
.note-bar {
box-sizing: border-box;
position: absolute;
Expand All @@ -278,6 +272,7 @@ const lyricStyle = computed(() => ({
border-radius: 5px;
}
// ノートの左右の端
.note-edge {
position: absolute;
top: 0;
Expand All @@ -287,15 +282,16 @@ const lyricStyle = computed(() => ({
height: 100%;
&.left {
left: -2px;
left: -2px; // FIXME: 右端のノートの当たり判定に食い込んでしまう
border-radius: 5px 0 0 5px;
}
&.right {
right: -2px;
right: -2px; // FIXME: 左端のノートの当たり判定に食い込んでしまう
border-radius: 0 5px 5px 0;
}
}
// ノートの歌詞
.note-lyric {
position: absolute;
bottom: 100%;
Expand All @@ -311,7 +307,7 @@ const lyricStyle = computed(() => ({
}
}
// 編集モード
// ノート編集モード
.note.edit {
.note-bar {
cursor: move;
Expand Down Expand Up @@ -343,7 +339,14 @@ const lyricStyle = computed(() => ({
}
// 右リサイズ中
&.resizing-right {
&.resize-note-right {
.note-bar {
cursor: ew-resize;
}
.note-edge:hover {
cursor: ew-resize;
}
.note-edge.right {
background-color: var(--scheme-color-sing-note-bar-selected-border);
}
Expand All @@ -356,7 +359,14 @@ const lyricStyle = computed(() => ({
}
// 左リサイズ中
&.resizing-left {
&.resize-note-left {
.note-bar {
cursor: ew-resize;
}
.note-edge:hover {
cursor: ew-resize;
}
.note-edge.left {
background-color: var(--scheme-color-sing-note-bar-selected-border);
}
Expand Down Expand Up @@ -419,18 +429,8 @@ const lyricStyle = computed(() => ({
}
}
// リサイズ中
&.resizing {
.note-bar {
cursor: ew-resize;
}
.note-edge:hover {
cursor: ew-resize;
}
}
// ドラッグ移動中
&.move {
&.move-note {
cursor: move;
}
}
Expand Down
36 changes: 15 additions & 21 deletions src/components/Sing/SequencerRuler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,36 +107,30 @@ const endTicks = computed(() => {
const width = computed(() => {
return tickToBaseX(endTicks.value, tpqn.value) * zoomX.value;
});
// measureInfosの計算を調整
const measureInfos = computed(() => {
const measureInfos: {
number: number;
x: number;
}[] = [];
for (let i = 0; i < timeSignatures.value.length; i++) {
const ts = timeSignatures.value[i];
return timeSignatures.value.flatMap((timeSignature, i) => {
const measureDuration = getMeasureDuration(
ts.beats,
ts.beatType,
timeSignature.beats,
timeSignature.beatType,
tpqn.value,
);
const nextTsPosition =
i !== timeSignatures.value.length - 1
? tsPositions.value[i + 1]
: undefined;
let measureNumber = ts.measureNumber;
let measurePosition = tsPositions.value[i];
while (measurePosition < (nextTsPosition ?? endTicks.value)) {
: endTicks.value;
const start = tsPositions.value[i];
const end = nextTsPosition;
const numMeasures = Math.floor((end - start) / measureDuration);
return Array.from({ length: numMeasures }, (_, index) => {
const measureNumber = timeSignature.measureNumber + index;
const measurePosition = start + index * measureDuration;
const baseX = tickToBaseX(measurePosition, tpqn.value);
measureInfos.push({
return {
number: measureNumber,
x: Math.round(baseX * zoomX.value),
});
measureNumber++;
measurePosition += measureDuration;
}
}
return measureInfos;
};
});
});
});
const playheadX = computed(() => {
const baseX = tickToBaseX(playheadTicks.value, tpqn.value);
Expand Down Expand Up @@ -227,7 +221,7 @@ onUnmounted(() => {
stroke: var(--scheme-color-sing-ruler-measure-line);
stroke-width: 1px;
// NOTE: 最初の小節線を非表示: 必要に応じて再表示+位置合わせする
// NOTE: 最初の小節線を非表示必要に応じて再表示位置合わせする
&.first-measure-line {
stroke: var(--scheme-color-sing-ruler-surface);
}
Expand Down
8 changes: 8 additions & 0 deletions src/type/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -746,3 +746,11 @@ export interface MessageBoxReturnValue {
export const SandboxKey = "backend";

export type EditorType = "talk" | "song";

export type PreviewMode =
| "ADD_NOTE"
| "MOVE_NOTE"
| "RESIZE_NOTE_RIGHT"
| "RESIZE_NOTE_LEFT"
| "DRAW_PITCH"
| "ERASE_PITCH";

0 comments on commit caeb71c

Please sign in to comment.