75 lines
2.0 KiB
Vue
75 lines
2.0 KiB
Vue
<template>
|
|
<div
|
|
v-if="!highlighted || highlighted === room.id"
|
|
:class="[
|
|
highlighted
|
|
? ''
|
|
: 'flex cursor-pointer items-center justify-center transition-transform hover:scale-105',
|
|
' absolute',
|
|
]"
|
|
:style="roomPositionCSS"
|
|
>
|
|
<div
|
|
class="pointer-events-auto absolute"
|
|
:style="roomPolygonCSS"
|
|
@click.stop="clickOnRoom($event)"
|
|
@mousemove="moveOverRoom($event)"
|
|
></div>
|
|
<span class="pointer-events-none z-10" v-if="!highlighted">{{
|
|
room.displayName
|
|
}}</span>
|
|
<slot />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue';
|
|
import { RoomLayoutObject } from '../../../interfaces/room.interfaces';
|
|
|
|
const props = defineProps<{
|
|
room: RoomLayoutObject;
|
|
zoom: number;
|
|
highlighted?: number;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'clickedIn', x: number, y: number): void;
|
|
(e: 'mouseMovedIn', x: number, y: number): void;
|
|
}>();
|
|
const mouseCoordsFromEvent = (ev: MouseEvent): [number, number] => {
|
|
const rect = (ev.target as HTMLElement).getBoundingClientRect();
|
|
return [
|
|
(ev.clientX - rect.left) / props.zoom,
|
|
(ev.clientY - rect.top) / props.zoom,
|
|
];
|
|
};
|
|
const clickOnRoom = (ev: MouseEvent) =>
|
|
emit('clickedIn', ...mouseCoordsFromEvent(ev));
|
|
const moveOverRoom = (ev: MouseEvent) =>
|
|
emit('mouseMovedIn', ...mouseCoordsFromEvent(ev));
|
|
|
|
const roomPolygonCSS = computed(() => {
|
|
if (!props.room) return {};
|
|
const [min, max] = props.room.boundingBox;
|
|
return {
|
|
clipPath: `polygon(${props.room.plan
|
|
.map((point) => `${point[0] - min[0]}px ${point[1] - min[1]}px`)
|
|
.join(', ')})`,
|
|
width: `${max[0] - min[0]}px`,
|
|
height: `${max[1] - min[1]}px`,
|
|
backgroundColor: 'rgb(40 180 255 / 40%)',
|
|
};
|
|
});
|
|
|
|
const roomPositionCSS = computed(() => {
|
|
if (!props.room) return {};
|
|
const [min, max] = props.room.boundingBox;
|
|
return {
|
|
top: `${min[1]}px`,
|
|
left: `${min[0]}px`,
|
|
width: `${max[0] - min[0]}px`,
|
|
height: `${max[1] - min[1]}px`,
|
|
};
|
|
});
|
|
</script>
|