update
This commit is contained in:
@@ -4,35 +4,47 @@
|
||||
<div class="beat-main-container">
|
||||
<div class="beat-track-container" :class="{ dragging }">
|
||||
<template v-if="beat.displaySticking.value">
|
||||
<div v-for="(_, type) in TrackUnitStickingTypeList.slice(1)"
|
||||
class="beat-line">
|
||||
<icon color="var(--color-ui-neutral-light)" :icon-name="StickingTypeIconMap[TrackUnitStickingTypeList[type + 1]!]" />
|
||||
<sticking-track-view
|
||||
:beat-index="beatIndex"
|
||||
:sticking-type="type + 1" />
|
||||
</div>
|
||||
<div v-for="(_, type) in TrackUnitStickingTypeList.slice(1)"
|
||||
class="beat-line">
|
||||
<icon color="var(--color-ui-neutral-light)" :icon-name="StickingTypeIconMap[TrackUnitStickingTypeList[type + 1]!]" />
|
||||
<sticking-track-view
|
||||
:beat-index="beatIndex"
|
||||
:sticking-type="type + 1" />
|
||||
</div>
|
||||
</template>
|
||||
<draggable v-else
|
||||
<VueDraggableNext v-else
|
||||
@start="dragging = true"
|
||||
@end="dragging = false"
|
||||
animation="150"
|
||||
ghost-class="ghost"
|
||||
handle=".handle"
|
||||
:list="tracks"
|
||||
:list="tracks"
|
||||
@change="onMove"
|
||||
item-key="index">
|
||||
<template #item="{ element }">
|
||||
<div v-if="element.track.visible.value" class="beat-line">
|
||||
<div class="track-actions">
|
||||
<span class="handle track-action"><icon color="var(--color-ui-neutral-dark)" icon-name="list" /></span>
|
||||
<span class="track-action" @click="applyToolToTrack(element.track)"><icon color="var(--color-ui-neutral-dark)" icon-name="snowflake" /></span>
|
||||
<transition-group name="fade">
|
||||
<template v-for="element in tracks">
|
||||
<div v-if="element.track.visible.value" class="beat-line" :key="element.index">
|
||||
<div class="track-actions">
|
||||
<span class="track-action">
|
||||
<icon color="var(--color-ui-neutral-dark)"
|
||||
@click="element.track.visible.value = !element.track.visible.value"
|
||||
:icon-name="element.track.visible.value ? 'eye' : 'eyeOff'" />
|
||||
</span>
|
||||
<span class="track-action"
|
||||
@click="applyToolToTrack(element.track)">
|
||||
<icon color="var(--color-ui-neutral-dark)" icon-name="paintBucket" />
|
||||
</span>
|
||||
<span class="handle track-action">
|
||||
<icon color="var(--color-ui-neutral-dark)" icon-name="list" />
|
||||
</span>
|
||||
</div>
|
||||
<editable-text-field class="track-name" v-model="element.track.name.value" />
|
||||
<track-view :beat-index="beatIndex"
|
||||
:track-index="element.index" />
|
||||
</div>
|
||||
<editable-text-field class="track-name" v-model="element.track.name.value" />
|
||||
<track-view :beat-index="beatIndex"
|
||||
:track-index="element.index" />
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</template>
|
||||
</transition-group>
|
||||
</VueDraggableNext>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -44,7 +56,7 @@
|
||||
import EditableTextField from "@/ui/Widgets/EditableTextField/EditableTextField.vue";
|
||||
import { useBeatStore } from '@/BeatStore';
|
||||
import { computed, ref } from "vue";
|
||||
import Draggable from "vuedraggable";
|
||||
import { VueDraggableNext } from "vue-draggable-next";
|
||||
import { TrackUnitStickingTypeList, type Track } from "@/Track";
|
||||
import Icon from "@/ui/Widgets/Icon/Icon.vue";
|
||||
import { StickingTypeIconMap } from "../TrackUnit/trackUnit";
|
||||
@@ -86,7 +98,6 @@
|
||||
function applyToolToTrack(track: Track) {
|
||||
track.applySelectedTool();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -126,16 +137,20 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.handle {
|
||||
cursor: move;
|
||||
color: var(--color-ui-neutral-dark);
|
||||
}
|
||||
|
||||
.track-actions {
|
||||
opacity: 0%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.track-action {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.handle {
|
||||
cursor: move;
|
||||
color: var(--color-ui-neutral-dark);
|
||||
}
|
||||
|
||||
.beat-line {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -209,5 +224,15 @@
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 200ms ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -9,18 +9,17 @@
|
||||
</div>
|
||||
<Teleport to="#dropdowns">
|
||||
<div
|
||||
v-if="visible"
|
||||
ref="dropdown"
|
||||
class="dropdown"
|
||||
:class="{ visible }"
|
||||
@onmouseleave="visible = false">
|
||||
@mouseleave="visible = false">
|
||||
<slot name="content" />
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
const trigger = ref<HTMLDivElement>();
|
||||
const dropdown = ref<HTMLDivElement>();
|
||||
@@ -28,13 +27,17 @@
|
||||
const visible = ref(false);
|
||||
const top = ref('0px');
|
||||
const left = ref('0px');
|
||||
const effectiveTop = computed(() => visible.value ? top.value : 0);
|
||||
const effectiveLeft = computed(() => visible.value ? left.value : 0);
|
||||
|
||||
function onMouseEnter(e: MouseEvent | TouchEvent) {
|
||||
visible.value = true;
|
||||
if (trigger.value) {
|
||||
const rect = trigger.value.getBoundingClientRect();
|
||||
top.value = rect.top + 'px';
|
||||
left.value = rect.width + rect.left + 'px';
|
||||
if (trigger.value && dropdown.value) {
|
||||
const rectTrigger = trigger.value.getBoundingClientRect();
|
||||
const rectDropdown = dropdown.value.getBoundingClientRect();
|
||||
console.log(rectDropdown);
|
||||
top.value = Math.min(window.innerHeight - rectDropdown.height, rectTrigger.top) + 'px';
|
||||
left.value = rectTrigger.width + rectTrigger.left + 'px';
|
||||
}
|
||||
window.addEventListener('touchstart', onWindowClick);
|
||||
window.addEventListener('click', onWindowClick);
|
||||
@@ -57,7 +60,7 @@
|
||||
}
|
||||
|
||||
function onMouseLeave(e: MouseEvent) {
|
||||
if (trigger.value && outside(e, trigger.value)) {
|
||||
if (trigger.value && outside(e, trigger.value) && dropdown.value && outside(e, dropdown.value)) {
|
||||
visible.value = false;
|
||||
}
|
||||
}
|
||||
@@ -66,8 +69,8 @@
|
||||
<style scoped lang="scss">
|
||||
.dropdown {
|
||||
position: absolute;
|
||||
top: v-bind(top);
|
||||
left: v-bind(left);
|
||||
top: v-bind(effectiveTop);
|
||||
left: v-bind(effectiveLeft);
|
||||
visibility: hidden;
|
||||
|
||||
&.visible {
|
||||
|
||||
@@ -13,6 +13,7 @@ import Floppy from "@/assets/svgs/floppy2-fill.svg";
|
||||
import Delete from "@/assets/svgs/delete.svg";
|
||||
import Eye from "@/assets/svgs/eye.svg";
|
||||
import EyeOff from "@/assets/svgs/eye-off.svg";
|
||||
import PaintBucket from '@/assets/svgs/paint-bucket.svg';
|
||||
|
||||
export const IconUrlMap = {
|
||||
arrowClockwise: ArrowClockwise,
|
||||
@@ -30,6 +31,7 @@ export const IconUrlMap = {
|
||||
delete: Delete,
|
||||
eye: Eye,
|
||||
eyeOff: EyeOff,
|
||||
paintBucket: PaintBucket,
|
||||
} as const;
|
||||
|
||||
export type IconName = keyof typeof IconUrlMap;
|
||||
|
||||
Reference in New Issue
Block a user