summaryrefslogtreecommitdiff
path: root/src/Map/Canvas.bak.js
blob: efc6c00c59752d0318c23514cf5af84ddd590cdc (plain)
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
113
114
115
116
117
118
119
120
121
122
import h from '../Util/DomUtil.js';
import { dist, AABB, QuadTree } from '../Geometry/Geometry.js';

class Canvas {
	constructor(parentId) {
		const parentElement= document.getElementById(parentId);

		this.canvas = h('canvas', parentElement.width, parentElement.height);
		this.context = this.canvas.getContext('2d');

		/* state */
		this.movingPoint = false;
		this.selectedPoint = null;

		/* callbacks */
		this.onMovePoint = (original, now) => console.log(original, now);

		/* transform */
		this.scale = 1;
		this.pan = { x: 0, y: 0 };

		/* mouse */
		this.mouse = { x: 0, y: 0 };

		/* retrieving points */
		this.points = [];
		this.tree = new QuadTree(this.canvas.width, this.canvas.height);

		/* event listeners */
		this.canvas.addEventListener('mousemove', e => {
			this.mouse.x = e.offsetX;
			this.mouse.y = e.offsetY;
			if (this.movingPoint) this.render();
		});

		this.canvas.addEventListener('click', e => {
			if (this.movingPoint) {
				this.dropPoint();
			}
			else {
				const pt = this.getClickedPoint(
					{ x: e.offsetX, y: e.offsetY }, 10
				);
				if (pt) this.grabPoint(pt);
			}
		});

		/* attach to parent */
		parentElement.appendChild(this.canvas);
	}

	/* transform a point to internal coordinates */
	transform(x, y) {
		return [
			(this.scale * x) - this.pan.x,
			(this.scale * y) - this.pan.y,
		];
	}

	/* data updates */
	updatePoints(points) {
		this.points = [];
		this.tree = new QuadTree(this.canvas.width, this.canvas.height);
		for (let pt of points) this.insertPoint(pt);
		this.render();
	}

	insertPoint(pt) {
		this.tree.insert(pt);
		this.points.push(pt);
	}

	/* drawing */
	drawPoint(pt) {
		const ct = this.context;
		ct.save();
		ct.beginPath();
		const [x, y] = this.transform(pt.x, pt.y);
		console.log(x,y);
		ct.arc(x, y, 10/this.scale, 0, 2*Math.PI);
		ct.closePath();
		ct.fill();
		ct.restore();
	}

	render() {
		this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
		for (let pt of this.points) this.drawPoint(pt);
		if (this.movingPoint) {
			const [x, y] = this.transform(this.mouse.x, this.mouse.y);
			this.drawPoint({x, y});
		}
	}

	/* handling input */
	grabPoint(pt) {
		this.tree.root.remove(pt);
		this.points = this.points.filter(point => (point.x !== pt.x || point.y !== pt.y));
		console.log(this.points);
		this.selectedPoint = pt;
		this.movingPoint = true;
		this.render();
	}

	dropPoint() {
		const [x, y] = this.transform(this.mouse.x, this.mouse.y);
		this.onMovePoint(this.selectedPoint, {x, y});
		this.movingPoint = false;
		this.selectedPoint = null;
	}
	
	getClickedPoint(clickLocation, maxDistance) {
		const [ x, y ] = this.transform(clickLocation.x, clickLocation.y);
		const clickPoint = { x, y };
		const closest = this.tree.closest(clickPoint);
		if (!closest) return null;
		if (dist(closest, clickPoint) < maxDistance) return closest;
		return null;
	}
}

export default Canvas;