CanvasState implementation

This commit is contained in:
Jörn-Michael Miehe 2023-01-31 14:21:06 +00:00
parent f3a73f8ad0
commit 9ee55fc5af
2 changed files with 50 additions and 37 deletions

View file

@ -13,11 +13,7 @@
:key="`rect-${index}`" :key="`rect-${index}`"
:rectangle="rect" :rectangle="rect"
/> />
<SVGRect <SVGRect v-if="preview_visible" :focused="true" :rectangle="preview_rect" />
v-if="preview_visible"
:focused="true"
:rectangle="preview_rectangle"
/>
</ThouCanvas> </ThouCanvas>
</template> </template>
@ -27,6 +23,12 @@ import { Vector2D, Rectangle } from "../rects/rectangles";
import ThouCanvas from "../rects/ThouCanvas.vue"; import ThouCanvas from "../rects/ThouCanvas.vue";
import SVGRect from "../rects/SVGRect.vue"; import SVGRect from "../rects/SVGRect.vue";
enum CanvasState {
Idle,
Drawing,
Dragging,
}
@Options({ @Options({
components: { components: {
ThouCanvas, ThouCanvas,
@ -35,20 +37,14 @@ import SVGRect from "../rects/SVGRect.vue";
}) })
export default class extends Vue { export default class extends Vue {
private readonly min_rect_area = 300; private readonly min_rect_area = 300;
private drawing = false; private state = CanvasState.Idle;
private preview_corner1 = new Vector2D(); private preview_rect = new Rectangle();
private preview_corner2 = new Vector2D();
private dragging = false;
private drag_rect?: Rectangle; private drag_rect?: Rectangle;
private drag_origin = new Vector2D(); private drag_origin = new Vector2D();
public rectangles: Rectangle[] = []; public rectangles: Rectangle[] = [];
private get preview_visible(): boolean { private get preview_visible(): boolean {
return this.drawing || this.dragging; return this.state !== CanvasState.Idle;
}
private get preview_rectangle(): Rectangle {
return new Rectangle(this.preview_corner1, this.preview_corner2);
} }
private pop_rectangle(point: Vector2D): Rectangle | undefined { private pop_rectangle(point: Vector2D): Rectangle | undefined {
@ -66,23 +62,22 @@ export default class extends Vue {
return; return;
} }
this.drawing = true; this.state = CanvasState.Drawing;
this.preview_corner1 = point; this.preview_rect = new Rectangle(point, point);
this.preview_corner2 = point;
} }
private draw_finish() { private draw_finish() {
if (!this.drawing) { if (this.state !== CanvasState.Drawing || this.preview_rect === undefined) {
return; return;
} }
this.drawing = false; this.state = CanvasState.Idle;
if (this.preview_rectangle.area < this.min_rect_area) { if (this.preview_rect.area < this.min_rect_area) {
return; return;
} }
this.rectangles.push(this.preview_rectangle); this.rectangles.push(this.preview_rect);
} }
private drag_start(event: MouseEvent, point: Vector2D) { private drag_start(event: MouseEvent, point: Vector2D) {
@ -96,30 +91,34 @@ export default class extends Vue {
return; return;
} }
this.dragging = true; this.state = CanvasState.Dragging;
this.drag_origin = point; this.drag_origin = point;
this.preview_corner1 = this.drag_rect.origin; this.preview_rect = this.drag_rect;
this.preview_corner2 = this.drag_rect.corner;
} }
private drag_finish() { private drag_finish() {
if (!this.dragging) { if (
this.state !== CanvasState.Dragging ||
this.preview_rect === undefined
) {
return; return;
} }
this.dragging = false; this.state = CanvasState.Idle;
this.rectangles.push(this.preview_rectangle); this.rectangles.push(this.preview_rect);
} }
private on_mousemove(event: MouseEvent, point: Vector2D) { private on_mousemove(event: MouseEvent, point: Vector2D) {
if (this.drawing) { if (this.preview_rect === undefined) {
this.preview_corner2 = point; return;
} else if (this.dragging && this.drag_rect) { }
const movement = point.minus(this.drag_origin);
this.preview_corner1 = this.drag_rect.origin.plus(movement); if (this.state === CanvasState.Drawing) {
this.preview_corner2 = this.drag_rect.corner.plus(movement); this.preview_rect = this.preview_rect.update(undefined, point);
} else if (this.state === CanvasState.Dragging && this.drag_rect) {
const movement = point.minus(this.drag_origin);
this.preview_rect = this.drag_rect.move(movement);
} }
} }

View file

@ -24,9 +24,9 @@ export class Rectangle {
private readonly corner_1: Vector2D; private readonly corner_1: Vector2D;
private readonly corner_2: Vector2D; private readonly corner_2: Vector2D;
constructor(corner_1: Vector2D, corner_2: Vector2D) { constructor(corner_1?: Vector2D, corner_2?: Vector2D) {
this.corner_1 = corner_1; this.corner_1 = corner_1 || new Vector2D();
this.corner_2 = corner_2; this.corner_2 = corner_2 || new Vector2D();
} }
public get origin(): Vector2D { public get origin(): Vector2D {
@ -71,6 +71,20 @@ export class Rectangle {
return point.x >= this.origin.x && return point.x >= this.origin.x &&
point.y >= this.origin.y && point.y >= this.origin.y &&
point.x <= this.corner.x && point.x <= this.corner.x &&
point.y <= this.corner.y point.y <= this.corner.y;
}
public update(corner_1?: Vector2D, corner_2?: Vector2D): Rectangle {
return new Rectangle(
corner_1 || this.corner_1,
corner_2 || this.corner_2,
);
}
public move(vector: Vector2D): Rectangle {
return new Rectangle(
this.corner_1.plus(vector),
this.corner_2.plus(vector),
);
} }
} }