homemanager-fe/src/components/house-planner/HousePlanner.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>