-
-
Notifications
You must be signed in to change notification settings - Fork 107
/
NodePalette.vue
75 lines (65 loc) · 2.41 KB
/
NodePalette.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<template>
<div class="baklava-node-palette" @contextmenu.stop.prevent="">
<section v-for="c in categories" :key="c.name">
<h1 v-if="c.name !== 'default'">
{{ c.name }}
</h1>
<PaletteEntry
v-for="(ni, nt) in c.nodeTypes"
:key="nt"
:type="nt"
:title="ni.title"
@pointerdown="onDragStart(nt, ni)"
/>
</section>
</div>
<transition name="fade">
<div v-if="draggedNode" class="baklava-dragged-node" :style="draggedNodeStyles">
<PaletteEntry :type="draggedNode.type" :title="draggedNode.nodeInformation.title" />
</div>
</transition>
</template>
<script setup lang="ts">
import { computed, CSSProperties, inject, Ref, ref, reactive } from "vue";
import { usePointer } from "@vueuse/core";
import { AbstractNode, INodeTypeInformation } from "@baklavajs/core";
import PaletteEntry from "./PaletteEntry.vue";
import { useViewModel, useTransform, useNodeCategories } from "../utility";
interface IDraggedNode {
type: string;
nodeInformation: INodeTypeInformation;
}
const { viewModel } = useViewModel();
const { x: mouseX, y: mouseY } = usePointer();
const { transform } = useTransform();
const categories = useNodeCategories(viewModel);
const editorEl = inject<Ref<HTMLElement | null>>("editorEl");
const draggedNode = ref<IDraggedNode | null>(null);
const draggedNodeStyles = computed<CSSProperties>(() => {
if (!draggedNode.value || !editorEl?.value) {
return {};
}
const { left, top } = editorEl.value.getBoundingClientRect();
return {
top: `${mouseY.value - top}px`,
left: `${mouseX.value - left}px`,
};
});
const onDragStart = (type: string, nodeInformation: INodeTypeInformation) => {
draggedNode.value = {
type,
nodeInformation,
};
const onDragEnd = () => {
const instance = reactive(new nodeInformation.type()) as AbstractNode;
viewModel.value.displayedGraph.addNode(instance);
const rect = editorEl!.value!.getBoundingClientRect();
const [x, y] = transform(mouseX.value - rect.left, mouseY.value - rect.top);
instance.position.x = x;
instance.position.y = y;
draggedNode.value = null;
document.removeEventListener("pointerup", onDragEnd);
};
document.addEventListener("pointerup", onDragEnd);
};
</script>