99 lines
2.5 KiB
Vue
99 lines
2.5 KiB
Vue
<script setup lang="ts">
|
|
const props = defineProps<{
|
|
tree: ItemTree
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
mount: [end: Element],
|
|
refresh: []
|
|
}>()
|
|
|
|
const item = props.tree
|
|
|
|
const {data : items} : ItemResponse = await useFetch(CDRAGON_BASE + "plugins/rcp-be-lol-game-data/global/default/v1/items.json")
|
|
const itemMap = reactive(new Map())
|
|
for(let item of items.value) {
|
|
itemMap.set(item.id, item)
|
|
}
|
|
|
|
import type { TreeItem } from '#build/components';
|
|
import pkg from 'svg-dom-arrows';
|
|
const { LinePath } = pkg;
|
|
|
|
const start : Ref<Element | null> = useTemplateRef("start")
|
|
const arrows : Array<pkg.LinePath> = []
|
|
|
|
onMounted(() => {
|
|
refreshArrows()
|
|
emit('mount', start.value!!)
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
for(let arrow of arrows) {
|
|
arrow.release()
|
|
}
|
|
})
|
|
|
|
function drawArrow(start : Element, end : Element) {
|
|
// console.log("drawArrow(", start, ", ", end, ")")
|
|
if(start == null || end == null) return;
|
|
|
|
const arrow = new LinePath({
|
|
start: {
|
|
element: start,
|
|
position: {
|
|
top: 0.5,
|
|
left: 1
|
|
}
|
|
},
|
|
end: {
|
|
element: end,
|
|
position: {
|
|
top: 0.5,
|
|
left: 0
|
|
}
|
|
},
|
|
style: 'stroke:var(--color-on-surface);stroke-width:3;fill:transparent;',
|
|
appendTo: document.body
|
|
})
|
|
arrows.push(arrow)
|
|
}
|
|
|
|
function refreshArrows() {
|
|
for(let arrow of arrows) {
|
|
arrow.redraw()
|
|
}
|
|
}
|
|
|
|
// Redraw arrows on window resize
|
|
addEventListener('resize', (_) => {
|
|
refreshArrows()
|
|
})
|
|
|
|
function handleSubtreeMount(end : Element) {
|
|
drawArrow(start.value!!, end)
|
|
refreshArrows()
|
|
emit('refresh')
|
|
}
|
|
function handleRefresh() {
|
|
refreshArrows()
|
|
emit('refresh')
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div style="display: flex; align-items: center;">
|
|
|
|
<div v-if="item.data != undefined && item.data != null" style="width: fit-content; height: fit-content;">
|
|
<img ref="start" class="item-img" width="64" height="64" :alt="item.data.toString()" :src="CDRAGON_BASE + mapPath(itemMap.get(item.data).iconPath)" />
|
|
<h3 style="width: fit-content; margin:auto; margin-bottom: 10px;">{{ item.count }}</h3>
|
|
</div>
|
|
|
|
<div style="margin-left: 30px;">
|
|
<div style="width: fit-content; height: fit-content;" v-for="child in item.children">
|
|
<TreeItem @refresh="handleRefresh" @mount="(end) => handleSubtreeMount(end)" :tree="child" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|