advent22/ui/src/components/rects/RectPad.vue

85 lines
1.9 KiB
Vue
Raw Normal View History

2023-01-17 18:25:56 +00:00
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1000 1000"
preserveAspectRatio="none"
@pointerdown="on_pointerdown"
@pointermove="on_pointermove"
@pointerup="on_pointerup"
>
<Rect
v-if="preview_state.visible"
:focused="true"
:rectangle="preview_rectangle"
/>
<Rect
v-for="(rect, index) in rectangles"
:key="'rect' + index"
:rectangle="rect"
/>
</svg>
</template>
<script lang="ts">
import { Vue, Options } from "vue-class-component";
import { Vector2D, Rectangle } from "./rectangles";
import Rect from "./Rect.vue";
function get_event_thous(event: MouseEvent): Vector2D {
if (event.currentTarget === null) {
return new Vector2D();
}
let target = event.currentTarget as Element;
return new Vector2D(
Math.round((event.offsetX / target.clientWidth) * 1000),
Math.round((event.offsetY / target.clientHeight) * 1000)
);
}
@Options({
components: {
Rect,
},
})
export default class RectPad extends Vue {
private preview_state = {
visible: false,
corner1: new Vector2D(),
corner2: new Vector2D(),
};
private readonly min_rect_area = 4;
private rectangles: Rectangle[] = [];
private on_pointerdown(event: MouseEvent) {
this.preview_state.visible = true;
this.preview_state.corner1 = get_event_thous(event);
this.preview_state.corner2 = get_event_thous(event);
}
private on_pointermove(event: MouseEvent) {
this.preview_state.corner2 = get_event_thous(event);
}
private on_pointerup() {
this.preview_state.visible = false;
if (this.preview_rectangle.area >= this.min_rect_area) {
this.rectangles.push(this.preview_rectangle);
}
}
private get preview_rectangle(): Rectangle {
return new Rectangle(
this.preview_state.corner1,
this.preview_state.corner2
).normalize();
}
}
</script>
<style scoped>
svg {
cursor: crosshair;
}
</style>