Skip to content

Commit

Permalink
動作およびCSS調整
Browse files Browse the repository at this point in the history
  • Loading branch information
romot-co committed Oct 18, 2024
1 parent f594378 commit e9a9800
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 29 deletions.
124 changes: 96 additions & 28 deletions src/components/Sing/SequencerLoopControl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
<div
class="sequencer-loop-control"
:class="{
'loop-disabled': !isLoopEnabled,
'loop-enabled': isLoopEnabled,
'loop-dragging': isDragging,
[cursorClass]: true,
}"
:style="{ height: adjustedHeight + 'px' }"
@click.stop
@contextmenu.prevent="onContextMenu"
>
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -31,28 +32,28 @@
y="0"
:width="loopEndX - loopStartX"
:height="8"
class="loop-range"
class="loop-range-area"
@click.stop="onLoopRangeClick"
/>
<rect
:x="loopStartX - offset"
y="0"
:width="loopEndX - loopStartX"
:height="4"
class="loop-range-visible"
class="loop-range"
@click.stop="onLoopRangeClick"
/>
<!-- ループ開始ハンドル -->
<path
:d="`M${loopStartX - offset},0 L${loopStartX - offset},12 L${loopStartX - offset + 10},0 Z`"
class="loop-handle loop-start-handle"
:class="{ 'loop-handle-disabled': loopStartTick === loopEndTick }"
:class="{ 'loop-handle-no-length': loopStartTick === loopEndTick }"
/>
<!-- ループ終了ハンドル -->
<path
:d="`M${loopEndX - offset},0 L${loopEndX - offset},12 L${loopEndX - offset - 10},0 Z`"
class="loop-handle loop-end-handle"
:class="{ 'loop-handle-disabled': loopStartTick === loopEndTick }"
:class="{ 'loop-handle-no-length': loopStartTick === loopEndTick }"
/>
<!-- ループ開始ドラッグ領域 -->
<rect
Expand All @@ -62,6 +63,7 @@
height="16"
class="loop-drag-area"
@mousedown.stop="onStartHandleMouseDown"
@dblclick.stop="onHandleDoubleClick"
/>
<!-- ループ終了ドラッグ領域 -->
<rect
Expand All @@ -71,8 +73,10 @@
height="16"
class="loop-drag-area"
@mousedown.stop="onEndHandleMouseDown"
@dblclick.stop="onHandleDoubleClick"
/>
</svg>
<ContextMenu :menudata="contextMenuData" />
</div>
</template>

Expand All @@ -83,6 +87,9 @@ import { useLoopControl } from "@/composables/useLoopControl";
import { useCursorState, CursorState } from "@/composables/useCursorState";
import { tickToBaseX, baseXToTick } from "@/sing/viewHelper";
import { getNoteDuration } from "@/sing/domain";
import ContextMenu, {
ContextMenuItemData,
} from "@/components/Menu/ContextMenu.vue";
const props = defineProps<{
width: number;
Expand Down Expand Up @@ -133,10 +140,10 @@ const adjustedHeight = computed(() =>
);
const onLoopAreaMouseDown = (event: MouseEvent) => {
if (event.button !== 0 || (event.ctrlKey && event.button === 0)) return;
if (isDragging.value) {
void stopDragging();
}
if (event.button !== 0) return;
const target = event.currentTarget as HTMLElement;
const rect = target.getBoundingClientRect();
const x = event.clientX - rect.left + props.offset;
Expand All @@ -163,8 +170,14 @@ const onEndHandleMouseDown = (event: MouseEvent) => {
startDragging("end", event);
};
const onHandleDoubleClick = () => {
// ハンドルのダブルクリックでループを0地点に設定する
void setLoopRange(0, 0);
};
// ドラッグ開始処理
const startDragging = (target: "start" | "end", event: MouseEvent) => {
if (event.button !== 0) return;
isDragging.value = true;
dragTarget.value = target;
dragStartX.value = event.clientX;
Expand All @@ -178,6 +191,7 @@ const startDragging = (target: "start" | "end", event: MouseEvent) => {
// ドラッグ中処理
const onDrag = (event: MouseEvent) => {
if (!isDragging.value || !dragTarget.value) return;
if (event.button !== 0) return;
// ドラッグ中のX座標
const dx = event.clientX - dragStartX.value;
Expand Down Expand Up @@ -241,6 +255,34 @@ const stopDragging = async () => {
window.removeEventListener("mouseup", stopDragging);
};
const onContextMenu = (event: MouseEvent) => {
event.preventDefault();
event.stopPropagation();
};
const contextMenu = ref<InstanceType<typeof ContextMenu>>();
const contextMenuData = computed<ContextMenuItemData[]>(() => {
return [
{
type: "button",
label: isLoopEnabled.value ? "ループ無効" : "ループ有効",
onClick: () => {
contextMenu.value?.hide();
void setLoopEnabled(!isLoopEnabled.value);
},
disableWhenUiLocked: true,
},
{
type: "button",
label: "ループを0地点にリセット",
onClick: () => {
contextMenu.value?.hide();
void setLoopRange(0, 0);
},
disableWhenUiLocked: true,
},
];
});
onUnmounted(() => {
setCursorState(CursorState.UNSET);
});
Expand All @@ -253,52 +295,78 @@ onUnmounted(() => {
left: 0;
width: 100%;
pointer-events: auto;
cursor: pointer;
&:not(.cursor-ew-resize) {
cursor: pointer;
&.cursor-ew-resize {
cursor: ew-resize;
}
&.loop-dragging .loop-range-visible {
fill: var(--scheme-color-outline-variant);
// ホバー時のループエリア
&:hover .loop-area {
fill: var(--scheme-color-sing-loop-area);
}
}
// ループエリア
.loop-area {
fill: transparent;
transition: fill 0.1s ease-out;
}
// ループ範囲
.loop-range {
fill: transparent;
}
.loop-range-visible {
fill: var(--scheme-color-primary-fixed-dim);
}
&-area {
fill: transparent;
}
.loop-disabled .loop-range-visible {
fill: var(--scheme-color-outline);
opacity: 1;
}
// ループハンドル
.loop-handle {
fill: var(--scheme-color-primary-fixed-dim);
stroke: var(--scheme-color-primary-fixed-dim);
stroke-width: 2;
fill: var(--scheme-color-outline);
stroke: var(--scheme-color-outline);
stroke-width: 0;
stroke-linejoin: round;
&.loop-handle-disabled {
fill: var(--scheme-color-secondary);
stroke: var(--scheme-color-secondary);
&-no-length {
opacity: 0.5;
}
}
.loop-disabled .loop-handle {
fill: var(--scheme-color-outline);
stroke: var(--scheme-color-outline);
}
// ドラッグエリア
.loop-drag-area {
fill: transparent;
cursor: ew-resize;
pointer-events: all;
}
// ドラッグ中の状態
.loop-dragging {
.loop-area {
fill: var(--scheme-color-sing-loop-area);
}
.loop-range {
opacity: 0.6;
}
}
// ループが有効な状態
.loop-enabled {
.loop-range {
fill: var(--scheme-color-primary-fixed-dim);
}
.loop-handle {
fill: var(--scheme-color-primary-fixed-dim);
stroke: var(--scheme-color-primary-fixed-dim);
&-no-length {
fill: var(--scheme-color-outline);
stroke: var(--scheme-color-outline);
}
}
}
</style>
2 changes: 1 addition & 1 deletion src/components/Sing/ToolBar/ToolBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ const goToZero = () => {
const { isLoopEnabled, setLoopEnabled } = useLoopControl();
const toggleLoop = () => {
setLoopEnabled(!isLoopEnabled.value);
void setLoopEnabled(!isLoopEnabled.value);
};
const volume = computed({
Expand Down
8 changes: 8 additions & 0 deletions src/styles/v2/sing-colors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,10 @@ SASSのmapなどで構造化+mixin一括処理などで処理可能ですが、
--scheme-color-sing-shadow-note: oklch(
var(--lr-84) var(--neutral-variant-c) var(--neutral-variant-h)
);

--scheme-color-sing-loop-area: oklch(
var(--lr-86) var(--neutral-variant-c) var(--neutral-variant-h)
);
}

/* ダークテーマ */
Expand Down Expand Up @@ -671,4 +675,8 @@ SASSのmapなどで構造化+mixin一括処理などで処理可能ですが、
--scheme-color-sing-shadow-note: oklch(
var(--lr-40) var(--neutral-variant-c) var(--neutral-variant-h)
);

--scheme-color-sing-loop-area: oklch(
var(--lr-34) var(--neutral-variant-c) var(--neutral-variant-h)
);
}

0 comments on commit e9a9800

Please sign in to comment.