mudlet-map-browser-script 0.0.13 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js DELETED
@@ -1,888 +0,0 @@
1
- import Translator from "@andreasremdt/simple-translator";
2
- import bootstrap from "bootstrap";
3
- import {MapReader, Renderer, Settings} from "mudlet-map-renderer";
4
- import {Preview} from "./preview";
5
- import {downloadTags, downloadVersion} from "./versions";
6
- import convert from "color-convert";
7
-
8
- const rainbow = ["#CC99C9", "#9EC1CF", "#9EE09E", "#FDFD97", "#FEB144", "#FF6663"];
9
- let pathPick = 0;
10
-
11
- const defaultLanguage = document.querySelector("html").getAttribute("lang") ?? "pl";
12
-
13
- var translator = new Translator({
14
- defaultLanguage: defaultLanguage,
15
- detectLanguage: false,
16
- selector: "[data-i18n]",
17
- debug: false,
18
- registerGlobally: "__",
19
- persist: true,
20
- persistKey: "preferred_language",
21
- filesLocation: "i18n",
22
- });
23
- window.translator = translator;
24
-
25
- if (location.hostname !== "") {
26
- translator
27
- .fetch([defaultLanguage], false)
28
- .then(json => {
29
- let defaultLanguage = {};
30
- document.querySelectorAll("[data-i18n]").forEach(item => {
31
- defaultLanguage[item.getAttribute("data-i18n")] = item.innerHTML;
32
- });
33
- translator.add(defaultLanguage, {...defaultLanguage, ...json});
34
- })
35
- .catch(e => console.log(`Cannot fetch translations. ${e.message}`));
36
-
37
- translator
38
- .fetch(["en"])
39
- .then(() => {
40
- translator.translatePageTo();
41
- })
42
- .catch(e => console.log(`Cannot fetch translations. ${e.message}`));
43
- } else if (typeof translations !== "undefined") {
44
- let defaultLanguage = {};
45
- document.querySelectorAll("[data-i18n]").forEach(item => {
46
- defaultLanguage[item.getAttribute("data-i18n")] = item.innerHTML;
47
- });
48
- translator.add("pl", {...defaultLanguage, ...translations.pl});
49
- translator.add("en", translations.en);
50
- }
51
-
52
- const urlSearchParams = new URLSearchParams(window.location.search);
53
- const params = Object.fromEntries(urlSearchParams.entries());
54
- const url = window.location.origin + window.location.pathname;
55
-
56
- const svgToDataURL = svgStr => {
57
- const encoded = encodeURIComponent(svgStr).replace(/'/g, "%27").replace(/"/g, "%22");
58
-
59
- const header = "data:image/svg+xml,";
60
- const dataUrl = header + encoded;
61
-
62
- return dataUrl;
63
- };
64
-
65
- import {downloadNpc, findNpc} from "./npc";
66
- let roomNpc = {};
67
- downloadNpc().then(value => (roomNpc = value));
68
-
69
- let position = localStorage.getItem("position");
70
- if (position) {
71
- position = JSON.parse(position);
72
- }
73
- class PageControls {
74
- constructor(reader) {
75
- this.map = document.querySelector("#map");
76
- this.map.addEventListener("roomSelected", event => this.selectRoom(event.detail));
77
- this.map.addEventListener("roomDeselected", () => this.deselectRoom());
78
- this.map.addEventListener("zoom", event => this.adjustZoomBar(event.detail));
79
- this.map.addEventListener("zoom", event => (this.zoom = event.detail.zoom));
80
- this.map.addEventListener("zoom", event => this.preview.update());
81
- this.map.addEventListener("drag", event => this.preview.update());
82
- this.map.addEventListener("goToArea", event =>
83
- setTimeout(() => {
84
- if (event.detail.id) {
85
- this.findRoom(event.detail.id);
86
- }
87
- })
88
- );
89
- this.reader = reader;
90
- this.select = document.querySelector("#area");
91
- this.infoBox = document.querySelector(".info-box");
92
- this.levels = document.querySelector(".levels");
93
- this.saveImageButton = document.querySelector(".save-image");
94
- this.saveSvgImageButton = document.querySelector(".save-image-svg");
95
- this.copyImageButton = document.querySelector(".copy-image");
96
- this.zoomButtons = document.querySelectorAll(".zoom-controls .btn");
97
- this.toastContainer = document.querySelector(".toast");
98
- this.searchModal = document.querySelector("#search");
99
- this.search = document.querySelector(".search-form");
100
- this.findPathForm = document.querySelector(".findpath-form");
101
- this.findPathModal = document.querySelector("#findpath");
102
- this.helpModal = document.querySelector("#help");
103
- this.zoomBar = document.querySelector(".progress-container");
104
- this.settingsModal = document.querySelector("#settings");
105
- this.settingsForm = document.querySelector("#settings form");
106
- this.resetSettingsButton = document.querySelector("#settings button[type='reset']");
107
- this.versions = document.querySelector("#versions");
108
- this.releaseDescription = document.querySelector(".release-description");
109
- this.settings = new Settings();
110
- this.preview = new Preview(this.map, this);
111
- this.versionBadge = document.querySelector(".version-number");
112
- this.languageSelector = document.querySelector(".lang-dropdown");
113
- this.currentLanguageFlag = document.querySelector(".current-language-flag");
114
- this.pathBox = document.querySelector(".path-box ul");
115
- this.areaModal = document.getElementById("area-info")
116
- this.zIndex = 0;
117
- this.settings.optimizeDrag = true;
118
- this.settings.preview = true;
119
- let loaded = localStorage.getItem("settings");
120
- if (loaded) {
121
- Object.assign(this.settings, JSON.parse(loaded));
122
- }
123
-
124
- if (this.versions) {
125
- this.versions.addEventListener("change", event => {
126
- this.replaceVersion(event.target.value);
127
- this.releaseDescription.innerHTML = event.target.selectedOptions[0].getAttribute("data-description");
128
- bootstrap.Modal.getInstance(this.helpModal).hide();
129
- });
130
-
131
- this.helpModal.addEventListener("shown.bs.modal", () => {
132
- if (this.versions.children.length == 0) {
133
- downloadTags(this.versions.getAttribute("data-tags")).then(tags => {
134
- tags.forEach(tag => {
135
- let option = document.createElement("option");
136
- option.setAttribute("value", tag.tag_name);
137
- option.setAttribute("data-description", tag.body.replaceAll("\n\n", "\n"));
138
- option.innerHTML = tag.tag_name;
139
- this.versions.append(option);
140
- });
141
- this.releaseDescription.innerHTML = this.versions.firstChild.getAttribute("data-description");
142
- });
143
- }
144
- });
145
- }
146
-
147
- this.saveImageButton?.addEventListener("click", () => this.saveImage());
148
- this.saveSvgImageButton?.addEventListener("click", event => {
149
- event.preventDefault();
150
- this.downloadImage();
151
- });
152
- this.copyImageButton?.addEventListener("click", () => this.copyImage());
153
-
154
- this.zoomButtons.forEach(item =>
155
- item.addEventListener("click", event => {
156
- let delta = parseFloat(event.currentTarget.getAttribute("data-factor"));
157
- this.renderer.controls.deltaZoom(delta);
158
- })
159
- );
160
-
161
- this.search.addEventListener("submit", event => {
162
- event.preventDefault();
163
- this.submitSearch(event);
164
- });
165
-
166
- this.findPathForm?.addEventListener("submit", event => {
167
- event.preventDefault();
168
- this.submitPathFind(event);
169
- });
170
-
171
- this.findPathModal?.addEventListener("shown.bs.modal", () => {
172
- this.findPathModal.querySelector("input").focus();
173
- });
174
-
175
- this.searchModal.addEventListener("shown.bs.modal", () => {
176
- this.searchModal.querySelector("input").focus();
177
- });
178
-
179
- this.settingsModal.addEventListener("show.bs.modal", () => {
180
- this.populateSettings(this.settings);
181
- });
182
-
183
- this.settingsModal.addEventListener("shown.bs.modal", () => {
184
- this.settingsModal.querySelector("input").focus();
185
- });
186
-
187
- this.settingsForm.addEventListener("submit", event => {
188
- event.preventDefault();
189
- this.handleSaveSettings();
190
- });
191
-
192
- this.resetSettingsButton.addEventListener("click", event => {
193
- event.preventDefault();
194
- this.resetSettings();
195
- });
196
-
197
- this.areaModal?.addEventListener("show.bs.modal", () => {
198
- this.populateAreaInfo(this.areaId, this.zIndex);
199
- })
200
-
201
- window.addEventListener("resize", () => {
202
- this.render();
203
- });
204
-
205
- this.translatePage();
206
- this.languageSelector.querySelectorAll("a").forEach(element => {
207
- element.addEventListener("click", event => {
208
- event.preventDefault();
209
- this.translatePage(element.getAttribute("data-lang"));
210
- });
211
- });
212
-
213
- this.paths = {};
214
- }
215
-
216
- init() {
217
- let area = this.reader.getAreas()[0].areaId;
218
- console.log(area)
219
- let zIndex = 0;
220
- if (params.loc) {
221
- this.findRoom(params.loc);
222
- history.replaceState(null, null, url);
223
- } else {
224
- if (params.area) {
225
- area = params.area;
226
- history.replaceState(null, null, url);
227
- } else if (position !== null && position.area) {
228
- area = position.area;
229
- zIndex = position.zIndex;
230
- }
231
- this.renderArea(area, zIndex);
232
- }
233
- }
234
-
235
- handleSaveSettings() {
236
- let inputs = this.settingsModal.querySelectorAll("input");
237
-
238
- let formData = {};
239
- inputs.forEach(element => {
240
- let name = element.getAttribute("name");
241
- let type = element.getAttribute("type");
242
- if (type === "checkbox") {
243
- formData[name] = element.checked;
244
- } else if (type === "number") {
245
- formData[name] = parseInt(element.value);
246
- } else {
247
- formData[name] = element.value;
248
- }
249
- });
250
-
251
- Object.assign(this.settings, formData);
252
-
253
- this.showToast(translator.translateForKey("settings-saved", translator.currentLanguage));
254
- bootstrap.Modal.getInstance(this.settingsModal).hide();
255
- this.saveSettings();
256
- this.render(true);
257
- }
258
-
259
- saveSettings() {
260
- localStorage.setItem("settings", JSON.stringify(this.settings));
261
- }
262
-
263
- render(force) {
264
- return this.renderArea(this.select.value, this.zIndex, force);
265
- }
266
-
267
- renderArea(areaId, zIndex, force) {
268
- return new Promise((resolve, reject) => {
269
- if (this.areaId !== areaId || this.zIndex !== zIndex || force) {
270
- this.map.addEventListener(
271
- "renderComplete",
272
- (event, renderer) => {
273
- this.preview.init(event.detail.controls).then(() => resolve());
274
- },
275
- {once: true}
276
- );
277
- this.areaId = areaId;
278
- this.zIndex = zIndex;
279
-
280
- localStorage.setItem("position", JSON.stringify({area: areaId, zIndex: zIndex}));
281
- document.querySelector("body").style.background = this.settings.mapBackground;
282
- let area = this.reader.getArea(areaId, zIndex);
283
- if (this.renderer) {
284
- this.renderer.clear();
285
- }
286
- this.renderer = new Renderer(this.map, this.reader, area, this.reader.getColors(), this.settings);
287
- this.select.value = areaId;
288
- this.populateLevelButtons(area.getLevels(), zIndex);
289
- this.hideRoomInfo();
290
-
291
- Object.entries(this.paths).forEach(([key, group]) => {
292
- group.remove();
293
- let [from, to] = key.split("#");
294
- this.findPath(from, to);
295
- });
296
-
297
- this.renderer.clearHighlight();
298
- if (this.settings.keepZoomLevel && this.zoom) {
299
- this.renderer.controls.setZoom(this.zoom);
300
- }
301
- } else {
302
- resolve();
303
- }
304
- });
305
- }
306
-
307
- genericSetup() {
308
- document.querySelectorAll(".btn").forEach(element => element.addEventListener("click", () => element.blur()));
309
- }
310
-
311
- populateLevelButtons(levelsSet, zIndex) {
312
- this.levels.innerHTML = "";
313
- if (levelsSet.size <= 1) {
314
- return;
315
- }
316
- let levelsSorted = Array.from(levelsSet).sort(function (a, b) {
317
- return a - b;
318
- });
319
-
320
- if (levelsSorted.length > 10) {
321
- let container = document.createElement("div");
322
- container.classList.add("dropdown");
323
- let button = document.createElement("button");
324
- button.classList.add("btn", "btn-secondary", "dropdown-toggle");
325
- button.setAttribute("type", "button");
326
- button.setAttribute("data-bs-toggle", "dropdown");
327
- button.append(document.createTextNode(zIndex));
328
- let menu = document.createElement("div");
329
- menu.classList.add("dropdown-menu");
330
- container.append(button);
331
- container.append(menu);
332
- for (let level of levelsSorted) {
333
- let link = document.createElement("a");
334
- link.classList.add("dropdown-item", "btn-level");
335
- link.setAttribute("href", "#");
336
- link.setAttribute("data-level", level);
337
- link.append(document.createTextNode(level));
338
- menu.append(link);
339
- }
340
- this.levels.append(container);
341
- } else {
342
- for (let level of levelsSorted) {
343
- let button = document.createElement("button");
344
- button.setAttribute("type", "button");
345
- button.setAttribute("data-level", level);
346
- button.classList.add("btn", "btn-level");
347
- if (level === zIndex) {
348
- button.classList.add("btn-primary");
349
- } else {
350
- button.classList.add("btn-secondary");
351
- }
352
- button.append(document.createTextNode(level));
353
- this.levels.append(button);
354
- }
355
- }
356
- this.levels.querySelectorAll(".btn-level").forEach(item => {
357
- item.addEventListener("click", event => {
358
- event.preventDefault();
359
- let zIndex = parseInt(event.target.getAttribute("data-level"));
360
- this.renderArea(this.select.value, zIndex);
361
- });
362
- });
363
- }
364
-
365
- populateAreaInfo(areaId, zIndex) {
366
- let area = this.reader.getArea(areaId, zIndex);
367
- this.areaModal.querySelector(".area-name").innerHTML = `${area.areaName} (id: ${area.areaId})`;
368
- this.areaModal.querySelector(".area-room-count").innerHTML = Object.keys(area.rooms).length;
369
- let areaExits = this.areaModal.querySelector(".area-exits");
370
- areaExits.innerHTML = ""
371
- Object.values(area.rooms).flatMap(room => this.getAreaExits(room)).forEach(([id, targetId]) => {
372
- let targetArea = this.reader.getAreaByRoomId(targetId)
373
- let li = document.createElement("li")
374
- let roomLink = document.createElement("a")
375
- roomLink.setAttribute("href", "#")
376
- roomLink.setAttribute("data-room", id)
377
- roomLink.appendChild(document.createTextNode(id))
378
- roomLink.addEventListener("click", event => {
379
- event.preventDefault();
380
- this.findRoom(parseInt(event.currentTarget.getAttribute("data-room")));
381
- });
382
- let arrow = document.createTextNode(" -> ")
383
- let targetLink = document.createElement("a")
384
- targetLink.setAttribute("href", "#")
385
- targetLink.setAttribute("data-room", targetId)
386
- targetLink.appendChild(document.createTextNode(`${targetId} (${targetArea.areaName})`))
387
- targetLink.addEventListener("click", event => {
388
- event.preventDefault();
389
- this.findRoom(parseInt(event.currentTarget.getAttribute("data-room")));
390
- });
391
- li.append(roomLink, arrow, targetLink)
392
- areaExits.appendChild(li);
393
- })
394
- }
395
-
396
- getAreaExits(room) {
397
- let exits = [];
398
- Object.values(room.exits).filter(target => this.isExitTarget(target)).forEach(exitId => exits.push([room.id, exitId]))
399
- Object.values(room.specialExits).filter(target => this.isExitTarget(target)).forEach(exitId => exits.push([room.id, exitId]))
400
- return exits
401
- }
402
-
403
- isExitTarget(destinationRoom) {
404
- let destRoom = this.reader.getRoomById(destinationRoom);
405
- return parseInt(destRoom.areaId) !== this.renderer.area.areaId;
406
- }
407
-
408
- populateSelectBox() {
409
- this.select.querySelectorAll("option").forEach(item => item.remove());
410
- this.reader
411
- .getAreas()
412
- .filter(area => area.rooms.length > 0 && area.areaName !== undefined && area.areaName !== "")
413
- .sort((a, b) => {
414
- var nameA = a.areaName.toLowerCase(),
415
- nameB = b.areaName.toLowerCase();
416
- if (nameA < nameB) return -1;
417
- if (nameA > nameB) return 1;
418
- return 0;
419
- })
420
- .forEach((areaElement, index) => {
421
- if (!areaElement.rooms.length) {
422
- return;
423
- }
424
- this.select.append(new Option(areaElement.areaName, areaElement.areaId));
425
- });
426
- this.select.addEventListener("change", event => {
427
- this.renderArea(event.target.value, 0);
428
- });
429
- }
430
-
431
- submitSearch() {
432
- bootstrap.Modal.getInstance(this.searchModal).hide();
433
- let inputs = this.search.querySelectorAll("input");
434
-
435
- let formData = {};
436
- inputs.forEach(element => {
437
- formData[element.name] = element.value;
438
- element.value = "";
439
- });
440
-
441
- if (formData.roomId !== undefined) {
442
- let roomId = formData.roomId.split(",");
443
- if (isNaN(roomId[0])) {
444
- roomId = findNpc(roomId);
445
- }
446
- this.findRooms(roomId);
447
- }
448
- }
449
-
450
- submitPathFind() {
451
- bootstrap.Modal.getInstance(this.findPathModal).hide();
452
- let inputs = this.findPathForm.querySelectorAll("input");
453
-
454
- let formData = {};
455
- inputs.forEach(element => {
456
- formData[element.name] = element.value;
457
- element.value = "";
458
- });
459
- if (this.findPath(formData["start-loc"], formData["end-loc"])) {
460
- this.findRoom(formData["start-loc"]);
461
- }
462
- }
463
-
464
- findRoom(id) {
465
- if (!id) {
466
- return;
467
- }
468
- let area = this.reader.getAreaByRoomId(id);
469
- if (area !== undefined) {
470
- this.renderArea(area.areaId, area.zIndex).then(() => {
471
- this.renderer.controls.setZoom(1);
472
- this.renderer.controls.centerRoom(id);
473
- });
474
- } else {
475
- this.showToast(translator.translateForKey("location-not-found", translator.currentLanguage));
476
- }
477
- }
478
-
479
- findRooms(rooms) {
480
- let area = this.reader.getAreaByRoomId(rooms[0]);
481
- if (area !== undefined) {
482
- this.renderArea(area.areaId, area.zIndex).then(() => {
483
- this.renderer.controls.centerRoom(rooms[0]);
484
- this.renderer.controls.setZoom(1);
485
- this.renderer.clearHighlight();
486
- rooms.forEach(room => {
487
- this.renderer.renderHighlight(room);
488
- });
489
- //this.renderer.controls.centerOnItem(this.renderer.highlights);
490
- });
491
- } else {
492
- this.showToast(translator.translateForKey("location-not-found", translator.currentLanguage));
493
- }
494
- }
495
-
496
- findPath(from, to) {
497
- let key = `${from}#${to}`;
498
- let pathColor = this.pathBox.querySelector(`[data-path-key='${key}'] input[type='color']`)?.value ?? rainbow[pathPick++ % rainbow.length];
499
- this.paths[key] = this.renderer.controls.renderPath(
500
- from,
501
- to,
502
- convert.hex.rgb(pathColor).map(item => item / 255)
503
- );
504
- if (!this.paths[key]) {
505
- delete this.paths[key];
506
- this.showToast(translator.translateForKey("no-path", translator.currentLanguage));
507
- pathPick--;
508
- return;
509
- }
510
- if (!this.pathBox.querySelector(`[data-path-key='${key}']`)) {
511
- let pathSelector = document.createElement("li");
512
- pathSelector.classList.add("list-group-item", "d-inline-flex", "align-items-center", "position-relative");
513
- pathSelector.setAttribute("data-path-key", key);
514
-
515
- let color = document.createElement("input");
516
- color.setAttribute("type", "color");
517
- color.classList.add("small-color", "me-2");
518
- color.value = pathColor;
519
- color.addEventListener("input", event => {
520
- this.paths[key].strokeColor = event.target.value;
521
- });
522
- pathSelector.appendChild(color);
523
-
524
- pathSelector.appendChild(document.createTextNode(`${from} -> ${to}`));
525
-
526
- let deletePath = document.createElement("span");
527
- deletePath.classList.add("badge", "bg-secondary", "position-absolute", "end-0", "me-2");
528
- deletePath.appendChild(document.createTextNode(translator.translateForKey("delete", translator.currentLanguage)));
529
- deletePath.onclick = () => {
530
- this.paths[key].remove();
531
- delete this.paths[key];
532
- pathSelector.remove();
533
-
534
- if (Object.keys(this.paths).length === 0) {
535
- this.pathBox.parentNode.classList.add("invisible");
536
- }
537
- };
538
- pathSelector.appendChild(deletePath);
539
- this.pathBox.appendChild(pathSelector);
540
- this.pathBox.parentNode.classList.remove("invisible");
541
- return true;
542
- }
543
- }
544
-
545
- adjustZoomBar(view) {
546
- let percentage = (view.zoom - view.minZoom) / (10 - view.minZoom);
547
-
548
- this.zoomBar.querySelector(".progress-bar").style.width = percentage * 100 + "%";
549
- if (!this.zoomBar.classList.contains("visible")) {
550
- this.zoomBar.classList.add("visible");
551
- this.zoomBar.classList.remove("hidden");
552
- this.progressTimeout = setTimeout(() => {
553
- this.zoomBar.classList.add("hidden");
554
- this.zoomBar.classList.remove("visible");
555
- }, 3000);
556
- } else {
557
- if (this.progressTimeout !== undefined) {
558
- clearTimeout(this.progressTimeout);
559
- this.progressTimeout = undefined;
560
- }
561
- this.progressTimeout = setTimeout(() => {
562
- this.zoomBar.classList.add("hidden");
563
- this.zoomBar.classList.remove("visible");
564
- }, 3000);
565
- }
566
- }
567
-
568
- selectRoom(room) {
569
- this.showRoomInfo(room);
570
- }
571
-
572
- deselectRoom() {
573
- this.hideRoomInfo();
574
- }
575
-
576
- showRoomInfo(room) {
577
- let bgColor = this.reader.getColors()[room.env] ?? [114, 1, 0]
578
- this.infoBox.style.border = `2px solid rgba(${bgColor[0]}, ${bgColor[1]}, ${bgColor[2]}, 0.5)`
579
- this.infoBox.style.display = "initial";
580
- this.infoBox.querySelector(".room-id").innerHTML = room.id;
581
- this.infoBox.querySelector(".room-link").setAttribute("href", `${url}?loc=${room.id}`);
582
- this.infoBox.querySelector(".room-name").innerHTML = room.name;
583
- this.infoBox.querySelector(".room-env").innerHTML = room.env;
584
- this.infoBox.querySelector(".coord-x").innerHTML = room.x;
585
- this.infoBox.querySelector(".coord-y").innerHTML = room.y;
586
- this.infoBox.querySelector(".coord-z").innerHTML = room.z;
587
- this.infoBox.querySelector(".room-hash").innerHTML = "";
588
- this.infoBox.querySelector(".room-hash").innerHTML = room.hash ?? "";
589
-
590
- this.infoExitsGroup(this.infoBox.querySelector(".exits"), room.exits);
591
- this.infoExitsGroup(this.infoBox.querySelector(".special"), room.specialExits);
592
-
593
- this.userDataGroup(this.infoBox.querySelector(".userData"), room.userData);
594
- this.npcDataGroup(this.infoBox.querySelector(".npc"), roomNpc[room.id] || {});
595
- }
596
-
597
- userDataGroup(container, userData) {
598
- let containerList = container.querySelector("ul");
599
- containerList.innerHTML = "";
600
- let show = false;
601
- for (let userDataKey in userData) {
602
- show = true;
603
- let dataElement = document.createElement("li");
604
- dataElement.classList = ["user-data"];
605
- let key = document.createElement("p");
606
- key.append(`${userDataKey}:`);
607
- let value = document.createElement("p");
608
- value.append(`${userData[userDataKey].replaceAll("\\n", "\n")}`)
609
- value.className = "value";
610
- dataElement.append(key, value)
611
- containerList.append(dataElement);
612
- }
613
- container.style.display = show ? "initial" : "none";
614
- }
615
-
616
- infoExitsGroup(container, exits) {
617
- let containerList = container.querySelector("ul");
618
- containerList.innerHTML = "";
619
- let show = false;
620
- for (let exit in exits) {
621
- show = true;
622
- containerList.append(this.infoExit(exit, exits[exit]));
623
- }
624
- container.style.display = show ? "initial" : "none";
625
- }
626
-
627
- npcDataGroup(container, npcs) {
628
- let containerList = container.querySelector("ul");
629
- containerList.innerHTML = "";
630
- let show = false;
631
- for (let npc in npcs) {
632
- show = true;
633
- let element = document.createElement("li");
634
- element.append(document.createTextNode(npcs[npc]));
635
- containerList.append(element);
636
- }
637
- container.style.display = show ? "initial" : "none";
638
- }
639
-
640
- infoExit(exit, id) {
641
- let exitElement = document.createElement("li");
642
-
643
- let exitDir = document.createElement("span");
644
- exitDir.setAttribute("data-i18n", exit);
645
- exitDir.innerHTML = this.translateDir(exit);
646
- exitElement.append(exitDir);
647
- exitElement.append(document.createTextNode(": "));
648
-
649
- let link = document.createElement("a");
650
- link.setAttribute("href", "#");
651
- link.setAttribute("data-room", id);
652
- link.innerHTML = id;
653
- link.addEventListener("click", event => {
654
- event.preventDefault();
655
- this.findRoom(parseInt(event.currentTarget.getAttribute("data-room")));
656
- });
657
- exitElement.append(link);
658
-
659
- let destRoom = this.reader.getRoomById(id);
660
- if (parseInt(destRoom.areaId) !== this.renderer.area.areaId) {
661
- let area = this.reader.getAreaProperties(destRoom.areaId);
662
- exitElement.append(document.createTextNode(" -> "));
663
- let areaLink = document.createElement("a");
664
- areaLink.setAttribute("href", "#");
665
- areaLink.setAttribute("data-room", destRoom.id);
666
- areaLink.innerHTML = area.areaName;
667
- areaLink.addEventListener("click", event => {
668
- event.preventDefault();
669
- this.findRoom(parseInt(event.currentTarget.getAttribute("data-room")));
670
- });
671
- exitElement.append(areaLink);
672
- }
673
-
674
- return exitElement;
675
- }
676
-
677
- showToast(text) {
678
- this.toastContainer.querySelector(".toast-body").innerHTML = text;
679
- bootstrap.Toast.getOrCreateInstance(this.toastContainer).show();
680
- }
681
-
682
- translateDir(dir) {
683
- return translator.translateForKey(dir) ?? dir;
684
- }
685
-
686
- translatePage(lang) {
687
- this.currentLanguageFlag.classList.remove(`flag-${translator.currentLanguage}`);
688
- if (lang) {
689
- translator.translatePageTo(lang);
690
- }
691
- this.currentLanguageFlag.classList.add(`flag-${translator.currentLanguage}`);
692
- }
693
-
694
- hideRoomInfo() {
695
- this.infoBox.style.display = "none";
696
- }
697
-
698
- populateSettings(settings) {
699
- for (let setting in settings) {
700
- let input = this.settingsModal.querySelector("#nav-map").querySelector("input[name='" + setting + "']");
701
- if (!input) {
702
- continue;
703
- }
704
- if (input.getAttribute("type") === "checkbox") {
705
- input.checked = settings[setting];
706
- } else if (input.getAttribute("type") === "color") {
707
- input.value = settings[setting].toCSS ? settings[setting].toCSS(true) : settings[setting];
708
- } else {
709
- input.value = settings[setting];
710
- }
711
- }
712
- }
713
-
714
- resetSettings() {
715
- let defaults = new Settings();
716
- defaults.preview = true;
717
- defaults.optimizeDrag = true;
718
- this.populateSettings(defaults);
719
- }
720
-
721
- saveImage() {
722
- let a = document.createElement("a");
723
- a.setAttribute("href", this.map.toDataURL());
724
- a.setAttribute("download", this.renderer.area.areaName + ".png");
725
- document.querySelector("body").append(a);
726
- a.click();
727
- a.remove();
728
- }
729
-
730
- downloadImage() {
731
- let a = document.createElement("a");
732
- a.setAttribute("href", svgToDataURL(this.renderer.exportSvg()));
733
- a.setAttribute("download", this.renderer.area.areaName + ".svg");
734
- document.querySelector("body").append(a);
735
- a.click();
736
- a.remove();
737
- }
738
-
739
- copyImage() {
740
- if (typeof ClipboardItem !== "undefined") {
741
- this.map.toBlob(blob => navigator.clipboard.write([new ClipboardItem({"image/png": blob})]));
742
- this.showToast(translator.translateForKey("copied", translator.currentLanguage));
743
- } else {
744
- this.showToast(translator.translateForKey("no-clipboard", translator.currentLanguage));
745
- }
746
- }
747
-
748
- move(x, y) {
749
- this.renderer.controls.move(x, y);
750
- this.preview.update()
751
- }
752
-
753
- goDirection(directionKey) {
754
- let fullDirection = dirsShortToLong(directionKey);
755
- if (this.renderer.controls.selected) {
756
- this.findRoom(this.renderer.controls.selected.exits[fullDirection]);
757
- }
758
- }
759
-
760
- registerKeyBoard() {
761
- let directionKeys = {
762
- Numpad1: "sw",
763
- Numpad2: "s",
764
- Numpad3: "se",
765
- Numpad4: "w",
766
- Numpad6: "e",
767
- Numpad7: "nw",
768
- Numpad8: "n",
769
- Numpad9: "ne",
770
- NumpadMultiply: "u",
771
- NumpadDivide: "d",
772
- };
773
-
774
- window.addEventListener("keydown", event => {
775
- if (this.settings.disableKeyBinds) {
776
- return;
777
- }
778
-
779
- if (event.code === "F1") {
780
- event.preventDefault();
781
- this.showHelp();
782
- }
783
-
784
- if (event.ctrlKey && event.code === "KeyF") {
785
- event.preventDefault();
786
- this.showSearch();
787
- }
788
- });
789
-
790
- window.addEventListener("resize", () => {
791
- this.render(true);
792
- });
793
-
794
- window.addEventListener("keydown", event => {
795
- if (document.querySelector("input:focus") || this.settings.disableKeyBinds) {
796
- return;
797
- }
798
-
799
- if (event.ctrlKey && event.code === "KeyS") {
800
- this.saveImage();
801
- event.preventDefault();
802
- }
803
-
804
- if (event.code === "Equal") {
805
- this.renderer.controls.deltaZoom(1.1);
806
- event.preventDefault();
807
- }
808
-
809
- if (event.code === "Minus") {
810
- this.renderer.controls.deltaZoom(0.9);
811
- event.preventDefault();
812
- }
813
-
814
- if (event.code === "ArrowUp") {
815
- this.move(0, -1);
816
- event.preventDefault();
817
- }
818
- if (event.code === "ArrowDown") {
819
- this.move(0, 1);
820
- event.preventDefault();
821
- }
822
- if (event.code === "ArrowLeft") {
823
- this.move(-1, 0);
824
- event.preventDefault();
825
- }
826
- if (event.code === "ArrowRight") {
827
- this.move(1, 0);
828
- event.preventDefault();
829
- }
830
-
831
- if (directionKeys.hasOwnProperty(event.code)) {
832
- this.goDirection(directionKeys[event.code]);
833
- event.preventDefault();
834
- }
835
- });
836
- }
837
-
838
- showHelp() {
839
- bootstrap.Modal.getOrCreateInstance(this.helpModal).show();
840
- }
841
-
842
- showSearch() {
843
- bootstrap.Modal.getOrCreateInstance(this.searchModal).show();
844
- }
845
-
846
- replaceVersion(tag) {
847
- downloadVersion(tag, this.versions.getAttribute("data-files")).then(data => {
848
- this.reader = new MapReader(data, colors);
849
- this.populateSelectBox();
850
- this.renderArea(controls.areaId, controls.zIndex, true).then(() => this.showToast(`Przeładowano wersję na ${tag}`));
851
- this.versionBadge.innerHTML = `v${tag}`;
852
- this.versionBadge.style.display = "initial";
853
- });
854
- }
855
- }
856
-
857
- let controls = new PageControls(new MapReader(mapData, colors));
858
- window.controls = controls;
859
- controls.genericSetup();
860
- controls.populateSelectBox();
861
- controls.init();
862
- controls.registerKeyBoard();
863
-
864
- let dirs = {
865
- north: "n",
866
- south: "s",
867
- east: "e",
868
- west: "w",
869
- northeast: "ne",
870
- northwest: "nw",
871
- southeast: "se",
872
- southwest: "sw",
873
- up: "u",
874
- down: "d",
875
- };
876
-
877
- function getKeyByValue(obj, val) {
878
- for (let k in obj) {
879
- if (obj.hasOwnProperty(k) && obj[k] === val) {
880
- return k;
881
- }
882
- }
883
- }
884
-
885
- function dirsShortToLong(dir) {
886
- let result = getKeyByValue(dirs, dir);
887
- return result !== undefined ? result : dir;
888
- }