-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmap.html
166 lines (146 loc) · 6.2 KB
/
map.html
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The Robloxian Archipelago</title>
<style>
#svgContainer {
width: 100vw;
height: 100vh;
overflow: hidden;
border: 1px solid black;
position: relative;
touch-action: none; /* Disable default touch actions */
}
#svgImage {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="svgContainer">
<!-- Replace this SVG link with your actual Robloxian Archipelago Map -->
<svg id="svgImage" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 1000" preserveAspectRatio="xMidYMid meet">
<image href="assets/TheRobloxianArchipelagoMapV1.svg" width="2000" height="1000" />
</svg>
</div>
<script>
const svgImage = document.getElementById("svgImage");
const svgContainer = document.getElementById("svgContainer");
let viewBox = { x: 0, y: 0, w: 2000, h: 1000 }; // Initial viewBox matching SVG dimensions
svgImage.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`);
let isPanning = false;
let startPoint = { x: 0, y: 0 };
let lastTouchCenter = null;
let scale = 1;
let initialPinchDistance = null;
// Helper function to sync viewBox after zoom or pan
function syncViewBox() {
svgImage.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`);
scale = svgImage.clientWidth / viewBox.w;
}
// Desktop: Mouse Wheel Zooming (Focus on cursor position)
svgContainer.onwheel = function (e) {
e.preventDefault();
const zoomFactor = 0.1; // Adjust zoom factor as needed
const w = viewBox.w;
const h = viewBox.h;
const mx = e.offsetX; // Mouse x relative to the container
const my = e.offsetY; // Mouse y relative to the container
// Calculate the zoom factor
const dw = w * zoomFactor * (e.deltaY > 0 ? 1 : -1); // Inverted zoom direction
const dh = h * zoomFactor * (e.deltaY > 0 ? 1 : -1);
// Adjust viewBox based on cursor position
viewBox = {
x: viewBox.x - (dw * mx / svgImage.clientWidth),
y: viewBox.y - (dh * my / svgImage.clientHeight),
w: viewBox.w + dw,
h: viewBox.h + dh
};
syncViewBox();
};
// Desktop: Mouse Dragging for Panning
svgContainer.onmousedown = function (e) {
isPanning = true;
startPoint = { x: e.clientX, y: e.clientY };
};
svgContainer.onmousemove = function (e) {
if (isPanning) {
const dx = (startPoint.x - e.clientX) / scale;
const dy = (startPoint.y - e.clientY) / scale;
viewBox = {
x: viewBox.x + dx,
y: viewBox.y + dy,
w: viewBox.w,
h: viewBox.h
};
syncViewBox();
startPoint = { x: e.clientX, y: e.clientY }; // Update start point for continuous dragging
}
};
svgContainer.onmouseup = function () {
isPanning = false;
};
svgContainer.onmouseleave = function () {
isPanning = false;
};
// Mobile: Touch Zooming & Panning (Focus on touch points)
svgContainer.ontouchstart = function (e) {
if (e.touches.length === 2) {
initialPinchDistance = getDistance(e.touches[0], e.touches[1]);
lastTouchCenter = getTouchCenter(e.touches[0], e.touches[1]);
} else if (e.touches.length === 1) {
startPoint = { x: e.touches[0].clientX, y: e.touches[0].clientY };
}
};
svgContainer.ontouchmove = function (e) {
e.preventDefault();
if (e.touches.length === 2 && initialPinchDistance) {
const newPinchDistance = getDistance(e.touches[0], e.touches[1]);
const pinchRatio = initialPinchDistance / newPinchDistance;
const dw = viewBox.w * (1 - pinchRatio);
const dh = viewBox.h * (1 - pinchRatio);
const center = getTouchCenter(e.touches[0], e.touches[1]);
viewBox = {
x: viewBox.x + (dw * center.x / svgImage.clientWidth),
y: viewBox.y + (dh * center.y / svgImage.clientHeight),
w: viewBox.w - dw,
h: viewBox.h - dh
};
initialPinchDistance = newPinchDistance;
syncViewBox();
} else if (e.touches.length === 1) {
const dx = (startPoint.x - e.touches[0].clientX) / scale;
const dy = (startPoint.y - e.touches[0].clientY) / scale;
viewBox = {
x: viewBox.x + dx,
y: viewBox.y + dy,
w: viewBox.w,
h: viewBox.h
};
syncViewBox();
startPoint = { x: e.touches[0].clientX, y: e.touches[0].clientY }; // Update start point for continuous dragging
}
};
svgContainer.ontouchend = function (e) {
if (e.touches.length === 1) {
startPoint = { x: e.touches[0].clientX, y: e.touches[0].clientY };
lastTouchCenter = null; // Reset last touch center when ending pinch
} else if (e.touches.length === 0) {
initialPinchDistance = null; // Reset pinch distance when no touches are active
}
};
function getDistance(touch1, touch2) {
return Math.sqrt(Math.pow(touch2.clientX - touch1.clientX, 2) + Math.pow(touch2.clientY - touch1.clientY, 2));
}
function getTouchCenter(touch1, touch2) {
return {
x: (touch1.clientX + touch2.clientX) / 2,
y: (touch1.clientY + touch2.clientY) / 2
};
}
</script>
</body>
</html>