Rework the structure to handle suppression (using ID instead of index). Add create history and removing.
This commit is contained in:
parent
9439dd2d95
commit
4433cf0e00
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Box, Position } from '#shared/canvas.util';
|
import type { Box, Position } from '#shared/canvas.util';
|
||||||
|
import type CanvasNodeEditor from './canvas/CanvasNodeEditor.vue';
|
||||||
type Direction = 'bottom' | 'top' | 'left' | 'right';
|
type Direction = 'bottom' | 'top' | 'left' | 'right';
|
||||||
const rotation: Record<Direction, string> = {
|
const rotation: Record<Direction, string> = {
|
||||||
top: "180",
|
top: "180",
|
||||||
|
|
@ -24,7 +25,7 @@ interface HistoryEvent<T extends Action = Action>
|
||||||
}
|
}
|
||||||
interface HistoryAction<T extends Action>
|
interface HistoryAction<T extends Action>
|
||||||
{
|
{
|
||||||
element: number;
|
element: string;
|
||||||
from: ActionMap[T];
|
from: ActionMap[T];
|
||||||
to: ActionMap[T];
|
to: ActionMap[T];
|
||||||
}
|
}
|
||||||
|
|
@ -71,9 +72,11 @@ import { labelCenter, getPath } from '#shared/canvas.util';
|
||||||
const canvas = defineModel<CanvasContent>({ required: true, });
|
const canvas = defineModel<CanvasContent>({ required: true, });
|
||||||
|
|
||||||
const dispX = ref(0), dispY = ref(0), minZoom = ref(0.1), zoom = ref(0.5);
|
const dispX = ref(0), dispY = ref(0), minZoom = ref(0.1), zoom = ref(0.5);
|
||||||
const focusing = ref<number>(), editing = ref<number>();
|
const focusing = ref<string>(), editing = ref<string>();
|
||||||
const canvasRef = useTemplateRef('canvasRef');
|
const canvasRef = useTemplateRef('canvasRef');
|
||||||
const nodes = useTemplateRef('nodes');
|
const nodes = useTemplateRef<InstanceType<typeof CanvasNodeEditor>[]>('nodes');
|
||||||
|
|
||||||
|
const focusedNode = computed(() => nodes.value?.find(e => !!e && e.id === focusing.value)), editedNode = computed(() => nodes.value?.find(e => !!e && e.id === editing.value));
|
||||||
|
|
||||||
const edges = computed(() => {
|
const edges = computed(() => {
|
||||||
return canvas.value.edges.map(e => {
|
return canvas.value.edges.map(e => {
|
||||||
|
|
@ -83,8 +86,6 @@ const edges = computed(() => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const history = ref<HistoryEvent[]>([]);
|
const history = ref<HistoryEvent[]>([]);
|
||||||
const historyPos = ref(-1);
|
const historyPos = ref(-1);
|
||||||
const historyCursor = computed(() => history.value.length > 0 && historyPos.value > -1 ? history.value[historyPos.value] : undefined);
|
const historyCursor = computed(() => history.value.length > 0 && historyPos.value > -1 ? history.value[historyPos.value] : undefined);
|
||||||
|
|
@ -199,79 +200,82 @@ onMounted(() => {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
function moveNode(index: number[], deltax: number, deltay: number)
|
function moveNode(ids: string[], deltax: number, deltay: number)
|
||||||
{
|
{
|
||||||
const actions: HistoryAction<'move'>[] = [];
|
const actions: HistoryAction<'move'>[] = [];
|
||||||
for(const i of index)
|
for(const id of ids)
|
||||||
{
|
{
|
||||||
const node = canvas.value.nodes[i];
|
const node = canvas.value.nodes.find(e => e.id === id)!;
|
||||||
|
|
||||||
actions.push({ element: i, from: { x: node.x - deltax, y: node.y - deltay }, to: { x: node.x, y: node.y } });
|
actions.push({ element: id, from: { x: node.x - deltax, y: node.y - deltay }, to: { x: node.x, y: node.y } });
|
||||||
}
|
}
|
||||||
|
|
||||||
addAction('move', actions);
|
addAction('move', actions);
|
||||||
}
|
}
|
||||||
function resizeNode(index: number[], deltax: number, deltay: number, deltaw: number, deltah: number)
|
function resizeNode(ids: string[], deltax: number, deltay: number, deltaw: number, deltah: number)
|
||||||
{
|
{
|
||||||
const actions: HistoryAction<'resize'>[] = [];
|
const actions: HistoryAction<'resize'>[] = [];
|
||||||
for(const i of index)
|
for(const id of ids)
|
||||||
{
|
{
|
||||||
const node = canvas.value.nodes[i];
|
const node = canvas.value.nodes.find(e => e.id === id)!;
|
||||||
|
|
||||||
actions.push({ element: i, from: { x: node.x - deltax, y: node.y - deltay, w: node.width - deltaw, h: node.height - deltah }, to: { x: node.x, y: node.y, w: node.width, h: node.height } });
|
actions.push({ element: id, from: { x: node.x - deltax, y: node.y - deltay, w: node.width - deltaw, h: node.height - deltah }, to: { x: node.x, y: node.y, w: node.width, h: node.height } });
|
||||||
}
|
}
|
||||||
|
|
||||||
addAction('resize', actions);
|
addAction('resize', actions);
|
||||||
}
|
}
|
||||||
function selectNode(index: number)
|
function selectNode(id: string)
|
||||||
{
|
{
|
||||||
if(focusing.value !== index)
|
if(focusing.value !== id)
|
||||||
{
|
{
|
||||||
unselectNode();
|
unselectNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.value![index]?.dom?.addEventListener('click', stopPropagation, { passive: true });
|
focusing.value = id;
|
||||||
canvasRef.value?.addEventListener('click', unselectNode, { once: true });
|
|
||||||
|
|
||||||
focusing.value = index;
|
focusedNode.value?.dom?.addEventListener('click', stopPropagation, { passive: true });
|
||||||
|
canvasRef.value?.addEventListener('click', unselectNode, { once: true });
|
||||||
}
|
}
|
||||||
function editNode(index: number)
|
function editNode(id: string)
|
||||||
{
|
{
|
||||||
nodes.value![index]?.dom?.addEventListener('wheel', stopPropagation, { passive: true });
|
editing.value = id;
|
||||||
nodes.value![index]?.dom?.addEventListener('dblclick', stopPropagation, { passive: true });
|
|
||||||
canvasRef.value?.addEventListener('click', unselectNode, { once: true });
|
|
||||||
|
|
||||||
editing.value = index;
|
focusedNode.value?.dom?.addEventListener('wheel', stopPropagation, { passive: true });
|
||||||
|
focusedNode.value?.dom?.addEventListener('dblclick', stopPropagation, { passive: true });
|
||||||
|
canvasRef.value?.addEventListener('click', unselectNode, { once: true });
|
||||||
}
|
}
|
||||||
function addNode(e: MouseEvent)
|
function createNode(e: MouseEvent)
|
||||||
{
|
{
|
||||||
let box = canvasRef.value?.getBoundingClientRect()!;
|
let box = canvasRef.value?.getBoundingClientRect()!;
|
||||||
canvas.value.nodes.push({ id: getID(16), x: (e.layerX / zoom.value) - box.width / 2 - 50, y: (e.layerY / zoom.value) - box.height / 2 - 25, width: 100, height: 50, type: 'text' });
|
const node: CanvasNode = { id: getID(16), x: (e.layerX / zoom.value) - box.width / 2 - 50, y: (e.layerY / zoom.value) - box.height / 2 - 25, width: 100, height: 50, type: 'text' };
|
||||||
|
canvas.value.nodes.push(node);
|
||||||
|
|
||||||
|
addAction('create', [{ element: node.id, from: undefined, to: node }]);
|
||||||
}
|
}
|
||||||
function removeNode(index: number[])
|
function removeNode(ids: string[])
|
||||||
{
|
{
|
||||||
/*const actions: HistoryAction<'remove'>[] = [];
|
const actions: HistoryAction<'remove'>[] = [];
|
||||||
unselectNode();
|
unselectNode();
|
||||||
|
|
||||||
for(const i of index)
|
for(const id of ids)
|
||||||
{
|
{
|
||||||
const [node] = canvas.value.nodes.splice(i, 1);
|
const index = canvas.value.nodes.findIndex(e => e.id === id);
|
||||||
actions.push({ element: i, from: node, to: undefined });
|
actions.push({ element: id, from: canvas.value.nodes.splice(index, 1)[0], to: undefined });
|
||||||
|
|
||||||
console.log("Removing %s", i);
|
console.log("Removing %s", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
addAction('remove', actions);*/
|
addAction('remove', actions);
|
||||||
}
|
}
|
||||||
function editNodeProperty<T extends keyof CanvasNode>(index: number[], property: T, value: CanvasNode[T])
|
function editNodeProperty<T extends keyof CanvasNode>(ids: string[], property: T, value: CanvasNode[T])
|
||||||
{
|
{
|
||||||
const actions: HistoryAction<'remove'>[] = [];
|
const actions: HistoryAction<'remove'>[] = [];
|
||||||
|
|
||||||
for(const i of index)
|
for(const id of ids)
|
||||||
{
|
{
|
||||||
const copy = JSON.parse(JSON.stringify(canvas.value.nodes[i])) as CanvasNode;
|
const copy = JSON.parse(JSON.stringify(canvas.value.nodes.find(e => e.id === id)!)) as CanvasNode;
|
||||||
canvas.value.nodes[i][property] = value;
|
canvas.value.nodes.find(e => e.id === id)![property] = value;
|
||||||
actions.push({ element: i, from: copy, to: canvas.value.nodes[i] });
|
actions.push({ element: id, from: copy, to: canvas.value.nodes.find(e => e.id === id)! });
|
||||||
}
|
}
|
||||||
|
|
||||||
addAction('property', actions);
|
addAction('property', actions);
|
||||||
|
|
@ -280,17 +284,17 @@ function editNodeProperty<T extends keyof CanvasNode>(index: number[], property:
|
||||||
const unselectNode = () => {
|
const unselectNode = () => {
|
||||||
if(focusing.value !== undefined)
|
if(focusing.value !== undefined)
|
||||||
{
|
{
|
||||||
nodes.value![focusing.value]?.dom?.removeEventListener('click', stopPropagation);
|
focusedNode.value?.dom?.removeEventListener('click', stopPropagation);
|
||||||
nodes.value![focusing.value]?.unselect();
|
focusedNode.value?.unselect();
|
||||||
}
|
}
|
||||||
focusing.value = undefined;
|
focusing.value = undefined;
|
||||||
|
|
||||||
if(editing.value !== undefined)
|
if(editing.value !== undefined)
|
||||||
{
|
{
|
||||||
nodes.value![editing.value]?.dom?.removeEventListener('wheel', stopPropagation);
|
editedNode.value?.dom?.removeEventListener('wheel', stopPropagation);
|
||||||
nodes.value![editing.value]?.dom?.removeEventListener('dblclick', stopPropagation);
|
editedNode.value?.dom?.removeEventListener('dblclick', stopPropagation);
|
||||||
nodes.value![editing.value]?.dom?.removeEventListener('click', stopPropagation);
|
editedNode.value?.dom?.removeEventListener('click', stopPropagation);
|
||||||
nodes.value![editing.value]?.unselect();
|
editedNode.value?.unselect();
|
||||||
}
|
}
|
||||||
editing.value = undefined;
|
editing.value = undefined;
|
||||||
};
|
};
|
||||||
|
|
@ -300,40 +304,49 @@ const undo = () => {
|
||||||
|
|
||||||
for(const action of historyCursor.value.actions)
|
for(const action of historyCursor.value.actions)
|
||||||
{
|
{
|
||||||
|
const node = canvas.value.nodes.find(e => e.id === action.element)!;
|
||||||
switch(historyCursor.value.event)
|
switch(historyCursor.value.event)
|
||||||
{
|
{
|
||||||
case 'move':
|
case 'move':
|
||||||
{
|
{
|
||||||
const a = action as HistoryAction<'move'>;
|
const a = action as HistoryAction<'move'>;
|
||||||
canvas.value.nodes[action.element].x = a.from.x;
|
node.x = a.from.x;
|
||||||
canvas.value.nodes[action.element].y = a.from.y;
|
node.y = a.from.y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'resize':
|
case 'resize':
|
||||||
{
|
{
|
||||||
const a = action as HistoryAction<'resize'>;
|
const a = action as HistoryAction<'resize'>;
|
||||||
canvas.value.nodes[action.element].x = a.from.x;
|
node.x = a.from.x;
|
||||||
canvas.value.nodes[action.element].y = a.from.y;
|
node.y = a.from.y;
|
||||||
canvas.value.nodes[action.element].width = a.from.w;
|
node.width = a.from.w;
|
||||||
canvas.value.nodes[action.element].height = a.from.h;
|
node.height = a.from.h;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'edit':
|
case 'edit':
|
||||||
{
|
{
|
||||||
const a = action as HistoryAction<'edit'>;
|
const a = action as HistoryAction<'edit'>;
|
||||||
canvas.value.nodes[action.element].label = a.from;
|
node.label = a.from;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'create':
|
||||||
|
{
|
||||||
|
const a = action as HistoryAction<'create'>;
|
||||||
|
const index = canvas.value.nodes.findIndex(e => e.id === action.element);
|
||||||
|
canvas.value.nodes.splice(index, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'remove':
|
case 'remove':
|
||||||
{
|
{
|
||||||
const a = action as HistoryAction<'remove'>;
|
const a = action as HistoryAction<'remove'>;
|
||||||
canvas.value.nodes.splice(action.element, 0, a.from!);
|
canvas.value.nodes.push(a.from!);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'property':
|
case 'property':
|
||||||
{
|
{
|
||||||
const a = action as HistoryAction<'property'>;
|
const a = action as HistoryAction<'property'>;
|
||||||
canvas.value.nodes[action.element] = a.from;
|
const index = canvas.value.nodes.findIndex(e => e.id === action.element);
|
||||||
|
canvas.value.nodes[index] = a.from;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -357,40 +370,49 @@ const redo = () => {
|
||||||
|
|
||||||
for(const action of historyCursor.value.actions)
|
for(const action of historyCursor.value.actions)
|
||||||
{
|
{
|
||||||
|
const node = canvas.value.nodes.find(e => e.id === action.element)!;
|
||||||
switch(historyCursor.value.event)
|
switch(historyCursor.value.event)
|
||||||
{
|
{
|
||||||
case 'move':
|
case 'move':
|
||||||
{
|
{
|
||||||
const a = action as HistoryAction<'move'>;
|
const a = action as HistoryAction<'move'>;
|
||||||
canvas.value.nodes[action.element].x = a.to.x;
|
node.x = a.to.x;
|
||||||
canvas.value.nodes[action.element].y = a.to.y;
|
node.y = a.to.y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'resize':
|
case 'resize':
|
||||||
{
|
{
|
||||||
const a = action as HistoryAction<'resize'>;
|
const a = action as HistoryAction<'resize'>;
|
||||||
canvas.value.nodes[action.element].x = a.to.x;
|
node.x = a.to.x;
|
||||||
canvas.value.nodes[action.element].y = a.to.y;
|
node.y = a.to.y;
|
||||||
canvas.value.nodes[action.element].width = a.to.w;
|
node.width = a.to.w;
|
||||||
canvas.value.nodes[action.element].height = a.to.h;
|
node.height = a.to.h;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'edit':
|
case 'edit':
|
||||||
{
|
{
|
||||||
const a = action as HistoryAction<'edit'>;
|
const a = action as HistoryAction<'edit'>;
|
||||||
canvas.value.nodes[action.element].label = a.to;
|
node.label = a.to;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'create':
|
||||||
|
{
|
||||||
|
const a = action as HistoryAction<'remove'>;
|
||||||
|
canvas.value.nodes.push(a.to!);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'remove':
|
case 'remove':
|
||||||
{
|
{
|
||||||
const a = action as HistoryAction<'remove'>;
|
const a = action as HistoryAction<'remove'>;
|
||||||
canvas.value.nodes.splice(action.element, 1);
|
const index = canvas.value.nodes.findIndex(e => e.id === action.element);
|
||||||
|
canvas.value.nodes.splice(index, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'property':
|
case 'property':
|
||||||
{
|
{
|
||||||
const a = action as HistoryAction<'property'>;
|
const a = action as HistoryAction<'property'>;
|
||||||
canvas.value.nodes[action.element] = a.to;
|
const index = canvas.value.nodes.findIndex(e => e.id === action.element);
|
||||||
|
canvas.value.nodes[index] = a.to;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -407,7 +429,7 @@ useShortcuts({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div ref="canvasRef" class="absolute top-0 left-0 overflow-hidden w-full h-full touch-none" :style="{ '--zoom-multiplier': (1 / Math.pow(zoom, 0.7)) }" @dblclick.left="addNode">
|
<div ref="canvasRef" class="absolute top-0 left-0 overflow-hidden w-full h-full touch-none" :style="{ '--zoom-multiplier': (1 / Math.pow(zoom, 0.7)) }" @dblclick.left="createNode">
|
||||||
<div class="flex flex-col absolute sm:top-2 top-10 left-2 z-[35] overflow-hidden gap-4">
|
<div class="flex flex-col absolute sm:top-2 top-10 left-2 z-[35] overflow-hidden gap-4">
|
||||||
<div class="border border-light-35 dark:border-dark-35 bg-light-10 dark:bg-dark-10">
|
<div class="border border-light-35 dark:border-dark-35 bg-light-10 dark:bg-dark-10">
|
||||||
<Tooltip message="Zoom avant" side="right">
|
<Tooltip message="Zoom avant" side="right">
|
||||||
|
|
@ -483,7 +505,7 @@ useShortcuts({
|
||||||
'transform-origin': 'center center',
|
'transform-origin': 'center center',
|
||||||
}" class="h-full">
|
}" class="h-full">
|
||||||
<div class="absolute top-0 left-0 w-full h-full pointer-events-none *:pointer-events-auto *:select-none touch-none">
|
<div class="absolute top-0 left-0 w-full h-full pointer-events-none *:pointer-events-auto *:select-none touch-none">
|
||||||
<div v-if="focusing !== undefined" class="absolute z-20 origin-bottom" :style="{transform: `translate(${canvas.nodes[focusing].x}px, ${canvas.nodes[focusing].y}px) translateY(-100%) translateY(-12px) translateX(-50%) translateX(${canvas.nodes[focusing].width / 2}px) scale(calc(1 / var(--tw-scale)))`}">
|
<div v-if="focusing !== undefined && focusedNode !== undefined" class="absolute z-20 origin-bottom" :style="{transform: `translate(${focusedNode.x}px, ${focusedNode.y}px) translateY(-100%) translateY(-12px) translateX(-50%) translateX(${focusedNode.width / 2}px) scale(calc(1 / var(--tw-scale)))`}">
|
||||||
<div class="border border-light-35 dark:border-dark-35 bg-light-10 dark:bg-dark-10 flex flex-row">
|
<div class="border border-light-35 dark:border-dark-35 bg-light-10 dark:bg-dark-10 flex flex-row">
|
||||||
<PopoverRoot>
|
<PopoverRoot>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
|
|
|
||||||
|
|
@ -38,17 +38,16 @@ import type { Direction } from '~/shared/canvas.util';
|
||||||
import FakeA from '../prose/FakeA.vue';
|
import FakeA from '../prose/FakeA.vue';
|
||||||
import type { CanvasNode } from '~/types/canvas';
|
import type { CanvasNode } from '~/types/canvas';
|
||||||
|
|
||||||
const { node, index, zoom } = defineProps<{
|
const { node, zoom } = defineProps<{
|
||||||
node: CanvasNode
|
node: CanvasNode
|
||||||
index: number
|
|
||||||
zoom: number
|
zoom: number
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'select', index: number): void,
|
(e: 'select', id: string): void,
|
||||||
(e: 'edit', index: number): void,
|
(e: 'edit', id: string): void,
|
||||||
(e: 'move', index: number, x: number, y: number): void,
|
(e: 'move', id: string, x: number, y: number): void,
|
||||||
(e: 'resize', index: number, x: number, y: number, w: number, h: number): void,
|
(e: 'resize', id: string, x: number, y: number, w: number, h: number): void,
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const dom = useTemplateRef('dom');
|
const dom = useTemplateRef('dom');
|
||||||
|
|
@ -59,7 +58,7 @@ function selectNode(e: Event) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
focusing.value = true;
|
focusing.value = true;
|
||||||
emit('select', index);
|
emit('select', node.id);
|
||||||
|
|
||||||
dom.value?.addEventListener('mousedown', dragstart, { passive: true });
|
dom.value?.addEventListener('mousedown', dragstart, { passive: true });
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +69,7 @@ function editNode(e: Event) {
|
||||||
e.stopImmediatePropagation();
|
e.stopImmediatePropagation();
|
||||||
|
|
||||||
dom.value?.removeEventListener('mousedown', dragstart);
|
dom.value?.removeEventListener('mousedown', dragstart);
|
||||||
emit('edit', index);
|
emit('edit', node.id);
|
||||||
}
|
}
|
||||||
function resizeNode(e: MouseEvent, x: number, y: number, w: number, h: number) {
|
function resizeNode(e: MouseEvent, x: number, y: number, w: number, h: number) {
|
||||||
e.stopImmediatePropagation();
|
e.stopImmediatePropagation();
|
||||||
|
|
@ -88,7 +87,7 @@ function resizeNode(e: MouseEvent, x: number, y: number, w: number, h: number) {
|
||||||
const resizeend = (e: MouseEvent) => {
|
const resizeend = (e: MouseEvent) => {
|
||||||
if(e.button !== 0)
|
if(e.button !== 0)
|
||||||
return;
|
return;
|
||||||
emit('resize', index, node.x - startx, node.y - starty, node.width - startw, node.height - starth);
|
emit('resize', node.id, node.x - startx, node.y - starty, node.width - startw, node.height - starth);
|
||||||
|
|
||||||
window.removeEventListener('mousemove', resizemove);
|
window.removeEventListener('mousemove', resizemove);
|
||||||
window.removeEventListener('mouseup', resizeend);
|
window.removeEventListener('mouseup', resizeend);
|
||||||
|
|
@ -123,7 +122,7 @@ const dragend = (e: MouseEvent) => {
|
||||||
window.removeEventListener('mouseup', dragend);
|
window.removeEventListener('mouseup', dragend);
|
||||||
|
|
||||||
if(node.x - lastx !== 0 && node.y - lasty !== 0)
|
if(node.x - lastx !== 0 && node.y - lasty !== 0)
|
||||||
emit('move', index, node.x - lastx, node.y - lasty);
|
emit('move', node.id, node.x - lastx, node.y - lasty);
|
||||||
};
|
};
|
||||||
const dragstart = (e: MouseEvent) => {
|
const dragstart = (e: MouseEvent) => {
|
||||||
if(e.button !== 0)
|
if(e.button !== 0)
|
||||||
|
|
@ -135,7 +134,7 @@ const dragstart = (e: MouseEvent) => {
|
||||||
window.addEventListener('mouseup', dragend, { passive: true });
|
window.addEventListener('mouseup', dragend, { passive: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
defineExpose({ unselect, dom });
|
defineExpose({ unselect, dom, ...node });
|
||||||
|
|
||||||
const style = computed(() => {
|
const style = computed(() => {
|
||||||
return node.color ? node.color?.class ?
|
return node.color ? node.color?.class ?
|
||||||
|
|
|
||||||
BIN
db.sqlite-wal
BIN
db.sqlite-wal
Binary file not shown.
Loading…
Reference in New Issue