141 lines
3.4 KiB
Vue
141 lines
3.4 KiB
Vue
<template>
|
|
<div class="relative h-full w-full bg-white">
|
|
<canvas ref="canvas" class="border-none" />
|
|
<PlannerToolbar>
|
|
<PlannerTool
|
|
v-for="toolItem of toolbar"
|
|
:icon="toolItem.icon"
|
|
:multiple="!!toolItem.children?.length"
|
|
:selected="tool === toolItem.tool"
|
|
@click="selectTool(toolItem.tool, toolItem.subTool)"
|
|
>
|
|
<template v-if="toolItem.children?.length">
|
|
<PlannerTool
|
|
v-for="subItem of toolItem.children"
|
|
:icon="subItem.icon"
|
|
:selected="
|
|
tool === subItem.tool &&
|
|
(!subItem.subTool || subItem.subTool === subTool)
|
|
"
|
|
@click.stop="selectTool(subItem.tool, subItem.subTool)"
|
|
/>
|
|
</template>
|
|
</PlannerTool>
|
|
</PlannerToolbar>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import {
|
|
PencilSquareIcon,
|
|
PencilIcon,
|
|
HomeIcon,
|
|
ArrowsPointingOutIcon,
|
|
ArrowDownOnSquareIcon,
|
|
} from '@heroicons/vue/24/outline';
|
|
import { useSessionStorage } from '@vueuse/core';
|
|
import { onMounted, ref, shallowRef } from 'vue';
|
|
import { HousePlanner } from '../../modules/house-planner';
|
|
import { Layer, ToolEvent } from '../../modules/house-planner/interfaces';
|
|
import { SubToolType, ToolType } from '../../modules/house-planner/types';
|
|
import { ToolbarTool } from './interfaces/toolbar.interfaces';
|
|
import PlannerTool from './PlannerTool.vue';
|
|
import PlannerToolbar from './PlannerToolbar.vue';
|
|
|
|
const canvas = ref();
|
|
const module = shallowRef(new HousePlanner());
|
|
const tool = ref<ToolType>('line');
|
|
const subTool = ref<SubToolType>('line');
|
|
const serializedLayers = useSessionStorage<Layer[]>(
|
|
'roomData',
|
|
[
|
|
{
|
|
index: 0,
|
|
name: 'Base',
|
|
color: '#00ddff',
|
|
contents: [],
|
|
visible: true,
|
|
active: true,
|
|
},
|
|
{
|
|
index: 1,
|
|
name: 'Rooms',
|
|
color: '#00ddff',
|
|
contents: [],
|
|
visible: true,
|
|
active: false,
|
|
},
|
|
],
|
|
{ writeDefaults: false }
|
|
);
|
|
|
|
const toolbar: ToolbarTool[] = [
|
|
{
|
|
title: 'Move',
|
|
icon: ArrowsPointingOutIcon,
|
|
tool: null,
|
|
},
|
|
{
|
|
title: 'Draw',
|
|
icon: PencilSquareIcon,
|
|
tool: 'line',
|
|
subTool: 'line',
|
|
children: [
|
|
{
|
|
title: 'Outlines',
|
|
icon: PencilIcon,
|
|
tool: 'line',
|
|
subTool: 'line',
|
|
},
|
|
{
|
|
title: 'Rooms',
|
|
icon: HomeIcon,
|
|
tool: 'line',
|
|
subTool: 'room',
|
|
},
|
|
{
|
|
title: 'Curves',
|
|
icon: ArrowDownOnSquareIcon,
|
|
tool: 'line',
|
|
subTool: 'curve',
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
const selectTool = (newTool: ToolType, newSubTool?: SubToolType) => {
|
|
if (newTool === tool.value && !newSubTool) {
|
|
newTool = null;
|
|
}
|
|
module.value.manager?.tools.setTool(newTool, newSubTool);
|
|
};
|
|
|
|
onMounted(() => {
|
|
const cleanUp = module.value.initialize(
|
|
canvas.value,
|
|
JSON.parse(JSON.stringify(serializedLayers.value))
|
|
);
|
|
|
|
const events: Record<string, (e: CustomEvent) => void> = {
|
|
'hpc:update': (e: CustomEvent) => {
|
|
serializedLayers.value = module.value.manager!.layers;
|
|
},
|
|
'hpc:tool': (e: CustomEvent<ToolEvent>) => {
|
|
tool.value = e.detail.primary;
|
|
subTool.value = e.detail.secondary;
|
|
},
|
|
};
|
|
|
|
Object.keys(events).forEach((event) =>
|
|
canvas.value.addEventListener(event, events[event])
|
|
);
|
|
|
|
return () => {
|
|
Object.keys(events).forEach((event) =>
|
|
canvas.value.removeEventListener(event, events[event])
|
|
);
|
|
cleanUp();
|
|
};
|
|
});
|
|
</script>
|