-
Notifications
You must be signed in to change notification settings - Fork 1
/
Mouse.ts
112 lines (90 loc) · 2.49 KB
/
Mouse.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { Vector2D as Vector } from "@coderosh/vector";
import Particle from "./Particle";
import type Heax from "./Heax";
class Mouse {
/**
* Instance of heax class
*/
public heax: Heax;
/**
* Position of mouse
*/
public pos = new Vector(0, 0);
/**
* If mouse is down
*/
public down = false;
/**
* Dragged particle
*/
public draggedParticle: Particle | null = null;
/**
* Highlight color
*/
public highlightColor: string = "black";
/**
* Select radius
*/
public selectRadius = 20;
/**
*
* @param heax Instance of heax class
*/
constructor(heax: Heax) {
this.heax = heax;
heax.canvas.addEventListener("mousedown", this.onStart);
heax.canvas.addEventListener("mousemove", this.onMove);
heax.canvas.addEventListener("mouseup", this.onEnd);
heax.canvas.addEventListener("touchstart", this.onStart);
heax.canvas.addEventListener("touchmove", (e) => this.onMove(e.touches[0]));
heax.canvas.addEventListener("touchend", this.onEnd);
heax.canvas.addEventListener("touchcancel", this.onEnd);
}
private onStart = () => {
this.down = true;
};
private onMove = (e: MouseEvent | Touch) => {
const rect = this.heax.canvas.getBoundingClientRect();
this.pos.x = e.clientX - rect.left;
this.pos.y = e.clientY - rect.top;
};
private onEnd = () => {
this.down = false;
this.draggedParticle = null;
};
/**
* Drag the nearest particle
* @param draw Draw a circle around neareat particle
*/
public drag(draw = true) {
if (!this.down) this.draggedParticle = this.nearestParticle();
if (!this.draggedParticle) return;
if (draw) this.draw();
if (this.down) this.draggedParticle.position = this.pos.copy();
}
private draw() {
const ctx: CanvasRenderingContext2D = this.heax.ctx;
const p = this.draggedParticle!;
ctx.beginPath();
ctx.arc(p.position.x, p.position.y, p.radius * 1.5, 0, Math.PI * 2);
ctx.strokeStyle = this.highlightColor;
ctx.lineWidth = 1;
ctx.stroke();
ctx.closePath();
}
private nearestParticle() {
let nearestDist = Infinity;
let particle_ = null;
for (const composite of this.heax.composites) {
for (const particle of composite.particles) {
const dist = this.pos.dist((particle as Particle).position);
if (dist < this.selectRadius && dist < nearestDist) {
nearestDist = dist;
particle_ = particle;
}
}
}
return particle_;
}
}
export default Mouse;