-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathSelectionBoxState.ts
76 lines (66 loc) · 2.56 KB
/
SelectionBoxState.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { MouseEvent, TouchEvent } from 'react';
import { AbstractDisplacementState, AbstractDisplacementStateEvent } from '../core-state/AbstractDisplacementState';
import { State } from '../core-state/State';
import { SelectionLayerModel } from '../entities/selection/SelectionLayerModel';
import { Point, Rectangle } from '@projectstorm/geometry';
import { ModelGeometryInterface } from '../core/ModelGeometryInterface';
export class SelectionBoxState extends AbstractDisplacementState {
layer: SelectionLayerModel;
constructor() {
super({
name: 'selection-box'
});
}
activated(previous: State) {
super.activated(previous);
this.layer = new SelectionLayerModel();
this.engine.getModel().addLayer(this.layer);
}
deactivated(next: State) {
super.deactivated(next);
this.layer.remove();
this.engine.repaintCanvas();
}
getBoxDimensions(event: AbstractDisplacementStateEvent): ClientRect {
let rel: Point;
if (event.event instanceof MouseEvent) {
rel = this.engine.getRelativePoint(event.event.clientX, event.event.clientY);
} else if (event.event instanceof TouchEvent) {
const touch = event.event.touches[0];
rel = this.engine.getRelativePoint(touch.clientX, touch.clientY);
}
return {
left: rel.x > this.initialXRelative ? this.initialXRelative : rel.x,
top: rel.y > this.initialYRelative ? this.initialYRelative : rel.y,
width: Math.abs(rel.x - this.initialXRelative),
height: Math.abs(rel.y - this.initialYRelative),
right: rel.x < this.initialXRelative ? this.initialXRelative : rel.x,
bottom: rel.y < this.initialYRelative ? this.initialYRelative : rel.y
};
}
fireMouseMoved(event: AbstractDisplacementStateEvent) {
this.layer.setBox(this.getBoxDimensions(event));
const relative = this.engine.getRelativeMousePoint({
clientX: this.initialX,
clientY: this.initialY
});
if (event.virtualDisplacementX < 0) {
relative.x -= Math.abs(event.virtualDisplacementX);
}
if (event.virtualDisplacementY < 0) {
relative.y -= Math.abs(event.virtualDisplacementY);
}
const rect = new Rectangle(relative, Math.abs(event.virtualDisplacementX), Math.abs(event.virtualDisplacementY));
for (let model of this.engine.getModel().getSelectionEntities()) {
if (((model as unknown) as ModelGeometryInterface).getBoundingBox) {
const bounds = ((model as unknown) as ModelGeometryInterface).getBoundingBox();
if (rect.containsPoint(bounds.getTopLeft()) && rect.containsPoint(bounds.getBottomRight())) {
model.setSelected(true);
} else {
model.setSelected(false);
}
}
}
this.engine.repaintCanvas();
}
}