-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
122 lines (111 loc) · 4.47 KB
/
Copy pathscript.js
File metadata and controls
122 lines (111 loc) · 4.47 KB
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
var ui = {mapX: 1000, mapY: 500, mapScale: 0.5, isDragging: false};
const MAPW = 5760, MAPH = 3240, MAX_OFFBOUNDS = 0.5;
var markers_promise = fetch('./markers.json')
.then((response) => response.json())
.then((json) => {
markers_info = json;
});
document.addEventListener("DOMContentLoaded", () => {
map = document.getElementById("map");
markers_promise.then(() => {
console.log(markers_info);
map.style.backgroundImage = `url('assets/map0.png')`;
setMapScale(ui.mapScale);
setMapPos(ui.mapX, ui.mapY);
});
map.addEventListener("touchstart", (e) => {
ui.isDragging = true;
startTouchGesture(e);
e.preventDefault();
});
map.addEventListener("touchmove", (e) => {
debug.innerHTML = `Move<br>`;
debug.innerHTML += `${ui.touchCount} touches<br>`;
if (ui.touchCount != e.targetTouches.length) {
startTouchGesture(e);
return;
}
let avgX = Array.prototype.reduce.call(e.targetTouches, (acc, touch) => acc + touch.clientX, 0)
/ e.targetTouches.length;
let avgY = Array.prototype.reduce.call(e.targetTouches, (acc, touch) => acc + touch.clientY, 0)
/ e.targetTouches.length;
drag(avgX, avgY);
map.children[0].style.left = avgX+"px";
map.children[0].style.top = avgY+"px";
debug.innerHTML += `X: ${ui.dragStartX}<br>`;
debug.innerHTML += `Y: ${ui.dragStartY}<br>`;
// Calculate new average touch distance if we're currently pinching
if (ui.pinchStart !== null && e.targetTouches.length > 1) {
let avgDistance = Array.prototype.reduce.call(e.targetTouches, (acc, touch) => {
return acc + Math.hypot(touch.clientX - (ui.dragStartX-ui.mapX)*ui.mapScale, touch.clientY - (ui.dragStartY-ui.mapY)*ui.mapScale);
}, 0) / e.targetTouches.length;
debug.innerHTML += `Pinch ${ui.pinchStart}<br>`;
debug.innerHTML += `Avg ${avgDistance}<br>`;
scale(avgDistance * ui.pinchStart / ui.mapScale, avgX, avgY);
}
e.preventDefault();
});
map.addEventListener("touchend", (e) => {
if (e.targetTouches.length == 0)
ui.isDragging = false;
});
map.addEventListener("mousedown", (e) => {
ui.isDragging = true;
ui.dragStartX = ui.mapX + e.clientX / ui.mapScale;
ui.dragStartY = ui.mapY + e.clientY / ui.mapScale;
});
map.addEventListener("mousemove", (e) => {
if (e.buttons == 0)
ui.isDragging = false;
else
drag(e.clientX, e.clientY);
});
map.addEventListener('wheel', (e) => {
if (!e.ctrlKey)
scale(1-Math.sign(e.deltaY)*0.3, e.clientX, e.clientY);
});
});
function startTouchGesture(e) {
ui.touchCount = e.targetTouches.length;
ui.dragStartX = Array.prototype.reduce.call(e.targetTouches, (acc, touch) => acc + touch.clientX, 0)
/ e.targetTouches.length / ui.mapScale + ui.mapX;
ui.dragStartY = Array.prototype.reduce.call(e.targetTouches, (acc, touch) => acc + touch.clientY, 0)
/ e.targetTouches.length / ui.mapScale + ui.mapY;
debug.innerHTML += `Start<br>`;
debug.innerHTML += `${ui.touchCount} touches<br>`;
debug.innerHTML += `X: ${ui.dragStartX}<br>`;
debug.innerHTML += `Y: ${ui.dragStartY}<br>`;
if (e.targetTouches.length > 1) {
let avgDistance = Array.prototype.reduce.call(e.targetTouches, (acc, touch) => {
return acc + Math.hypot(touch.clientX - (ui.dragStartX-ui.mapX)*ui.mapScale, touch.clientY - (ui.dragStartY-ui.mapY)*ui.mapScale);
}, 0) / e.targetTouches.length;
ui.pinchStart = ui.mapScale / avgDistance;
debug.innerHTML += `Pinch ${ui.pinchStart}<br>`;
debug.innerHTML += `Avg ${avgDistance}<br>`;
} else
ui.pinchStart = null;
}
function drag(newX, newY) {
setMapPos(ui.dragStartX - newX / ui.mapScale,
ui.dragStartY - newY / ui.mapScale);
}
function scale(factor, pivotX, pivotY) {
let targetX = pivotX / ui.mapScale;
let targetY = pivotY / ui.mapScale;
setMapScale(ui.mapScale * factor);
setMapPos(ui.mapX + targetX - pivotX / ui.mapScale,
ui.mapY + targetY - pivotY / ui.mapScale);
}
function setMapPos(x, y) {
let maxOffboundsX = map.clientWidth * MAX_OFFBOUNDS / ui.mapScale;
let maxOffboundsY = map.clientHeight * MAX_OFFBOUNDS / ui.mapScale;
ui.mapX = Math.max(-maxOffboundsX, Math.min(MAPW + maxOffboundsX - map.clientWidth / ui.mapScale, x));
ui.mapY = Math.max(-maxOffboundsY, Math.min(MAPH + maxOffboundsY - map.clientHeight / ui.mapScale, y));
map.style.backgroundPosition = `${-ui.mapX * ui.mapScale}px ${-ui.mapY * ui.mapScale}px`;
}
function setMapScale(factor) {
let minScale = Math.min(map.clientWidth / MAPW, map.clientHeight / MAPH);
let maxScale = 1;
ui.mapScale = Math.min(maxScale, Math.max(minScale, factor));
map.style.backgroundSize = MAPW / map.clientWidth * ui.mapScale * 100 + "%";
}