mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 01:41:22 +01:00
refactor: hotkeys
This commit is contained in:
parent
a15f60150f
commit
0dd7468184
9 changed files with 220 additions and 165 deletions
60
index.html
60
index.html
|
|
@ -374,7 +374,6 @@
|
||||||
data-t="tipRegenerate"
|
data-t="tipRegenerate"
|
||||||
data-tip="Click to generate a new map"
|
data-tip="Click to generate a new map"
|
||||||
data-shortcut="F2"
|
data-shortcut="F2"
|
||||||
onclick="regeneratePrompt()"
|
|
||||||
class="options"
|
class="options"
|
||||||
style="display: none"
|
style="display: none"
|
||||||
>
|
>
|
||||||
|
|
@ -5562,19 +5561,14 @@
|
||||||
<div id="exportMapData" style="display: none" class="dialog">
|
<div id="exportMapData" style="display: none" class="dialog">
|
||||||
<div style="margin-bottom: 0.3em; font-weight: bold">Download image</div>
|
<div style="margin-bottom: 0.3em; font-weight: bold">Download image</div>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button id="saveSVG" data-tip="Download the map as vector image (open directly in browser or Inkscape)">
|
||||||
onclick="saveSVG()"
|
|
||||||
data-tip="Download the map as vector image (open directly in browser or Inkscape)"
|
|
||||||
>
|
|
||||||
.svg
|
.svg
|
||||||
</button>
|
</button>
|
||||||
<button onclick="savePNG()" data-tip="Download visible part of the map as .png (lossless compressed)">
|
<button id="savePNG" data-tip="Download visible part of the map as .png (lossless compressed)">.png</button>
|
||||||
.png
|
<button id="saveJPEG" data-tip="Download visible part of the map as .jpeg (lossy compressed) image">
|
||||||
</button>
|
|
||||||
<button onclick="saveJPEG()" data-tip="Download visible part of the map as .jpeg (lossy compressed) image">
|
|
||||||
.jpeg
|
.jpeg
|
||||||
</button>
|
</button>
|
||||||
<button onclick="openSaveTiles()" data-tip="Split map into smaller png tiles and download as zip archive">
|
<button id="openSaveTiles" data-tip="Split map into smaller png tiles and download as zip archive">
|
||||||
tiles
|
tiles
|
||||||
</button>
|
</button>
|
||||||
<span data-tip="Check to not allow system to automatically hide labels">
|
<span data-tip="Check to not allow system to automatically hide labels">
|
||||||
|
|
@ -5608,10 +5602,10 @@
|
||||||
|
|
||||||
<div style="margin: 1em 0 0.3em; font-weight: bold">Export to GeoJSON</div>
|
<div style="margin: 1em 0 0.3em; font-weight: bold">Export to GeoJSON</div>
|
||||||
<div>
|
<div>
|
||||||
<button onclick="saveGeoJSON_Cells()" data-tip="Download cells data in GeoJSON format">cells</button>
|
<button id="saveGeoJSON_Cells" data-tip="Download cells data in GeoJSON format">cells</button>
|
||||||
<button onclick="saveGeoJSON_Routes()" data-tip="Download routes data in GeoJSON format">routes</button>
|
<button id="saveGeoJSON_Routes" data-tip="Download routes data in GeoJSON format">routes</button>
|
||||||
<button onclick="saveGeoJSON_Rivers()" data-tip="Download rivers data in GeoJSON format">rivers</button>
|
<button id="saveGeoJSON_Rivers" data-tip="Download rivers data in GeoJSON format">rivers</button>
|
||||||
<button onclick="saveGeoJSON_Markers()" data-tip="Download markers data in GeoJSON format">markers</button>
|
<button id="saveGeoJSON_Markers" data-tip="Download markers data in GeoJSON format">markers</button>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
GeoJSON format is used in GIS tools such as QGIS. Check out
|
GeoJSON format is used in GIS tools such as QGIS. Check out
|
||||||
|
|
@ -5622,12 +5616,12 @@
|
||||||
|
|
||||||
<div style="margin: 1em 0 0.3em; font-weight: bold">Export To JSON</div>
|
<div style="margin: 1em 0 0.3em; font-weight: bold">Export To JSON</div>
|
||||||
<div>
|
<div>
|
||||||
<button onclick="exportToJson('Full')" data-tip="Download full data in JSON">full</button>
|
<button id="exportToJson_Full" data-tip="Download full data in JSON">full</button>
|
||||||
<button onclick="exportToJson('Minimal')" data-tip="Download minimal data in JSON">minimal</button>
|
<button id="exportToJson_Minimal" data-tip="Download minimal data in JSON">minimal</button>
|
||||||
<button onclick="exportToJson('PackCells')" data-tip="Download map metadata and pack cells data in JSON">
|
<button id="exportToJson_PackCells" data-tip="Download map metadata and pack cells data in JSON">
|
||||||
pack cells
|
pack cells
|
||||||
</button>
|
</button>
|
||||||
<button onclick="exportToJson('GridCells')" data-tip="Download map metadata and grid cells data in JSON">
|
<button id="exportToJson_GridCells" data-tip="Download map metadata and grid cells data in JSON">
|
||||||
grid cells
|
grid cells
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -5644,14 +5638,12 @@
|
||||||
<div id="saveMapData" style="display: none" class="dialog">
|
<div id="saveMapData" style="display: none" class="dialog">
|
||||||
<div style="margin-top: 0.3em">
|
<div style="margin-top: 0.3em">
|
||||||
<strong>Save map to</strong>
|
<strong>Save map to</strong>
|
||||||
<button onclick="dowloadMap()" data-tip="Download .map file to your local disk" data-shortcut="Ctrl + S">
|
<button id="dowloadMap" data-tip="Download .map file to your local disk" data-shortcut="Ctrl + S">
|
||||||
machine
|
machine
|
||||||
</button>
|
</button>
|
||||||
<button onclick="saveToDropbox()" data-tip="Save .map file to your Dropbox" data-shortcut="Ctrl + C">
|
<button id="saveToDropbox" data-tip="Save .map file to your Dropbox" data-shortcut="Ctrl + C">dropbox</button>
|
||||||
dropbox
|
|
||||||
</button>
|
|
||||||
<button
|
<button
|
||||||
onclick="quickSave()"
|
id="quickSave"
|
||||||
data-tip="Save the project to browser storage. It can be unreliable"
|
data-tip="Save the project to browser storage. It can be unreliable"
|
||||||
data-shortcut="F6"
|
data-shortcut="F6"
|
||||||
>
|
>
|
||||||
|
|
@ -5668,29 +5660,22 @@
|
||||||
<div id="loadMapData" style="display: none" class="dialog">
|
<div id="loadMapData" style="display: none" class="dialog">
|
||||||
<div>
|
<div>
|
||||||
<strong>Load map from</strong>
|
<strong>Load map from</strong>
|
||||||
<button onclick="mapToLoad.click()" data-tip="Load .map file from your local disk">machine</button>
|
<button id="loadFromMachine" data-tip="Load .map file from your local disk">machine</button>
|
||||||
<button onclick="loadURL()" data-tip="Load .map file from URL (server should allow CORS)">URL</button>
|
<button id="loadURL" data-tip="Load .map file from URL (server should allow CORS)">URL</button>
|
||||||
<button onclick="quickLoad()" data-tip="Load map from browser storage (if saved before)">storage</button>
|
<button id="quickLoad" data-tip="Load map from browser storage (if saved before)">storage</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="loadFromDropbox">
|
<div id="loadFromDropbox">
|
||||||
<p style="margin-bottom: 0.3em">
|
<p style="margin-bottom: 0.3em">
|
||||||
From your Dropbox account
|
From your Dropbox account
|
||||||
<button
|
<button id="dropboxConnectButton" data-tip="Connect your Dropbox account to be able to load maps from it">
|
||||||
id="dropboxConnectButton"
|
|
||||||
onclick="connectToDropbox()"
|
|
||||||
data-tip="Connect your Dropbox account to be able to load maps from it"
|
|
||||||
>
|
|
||||||
Connect
|
Connect
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<select id="loadFromDropboxSelect" style="width: 22em"></select>
|
<select id="loadFromDropboxSelect" style="width: 22em"></select>
|
||||||
<div id="loadFromDropboxButtons" style="margin-bottom: 0.6em">
|
<div id="loadFromDropboxButtons" style="margin-bottom: 0.6em">
|
||||||
<button onclick="loadFromDropbox()" data-tip="Load .map file from your Dropbox">Load</button>
|
<button id="loadFromDropbox" data-tip="Load .map file from your Dropbox">Load</button>
|
||||||
<button
|
<button id="createSharableDropboxLink" data-tip="Select file and create a link to share with your friends">
|
||||||
onclick="createSharableDropboxLink()"
|
|
||||||
data-tip="Select file and create a link to share with your friends"
|
|
||||||
>
|
|
||||||
Share
|
Share
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -5698,7 +5683,7 @@
|
||||||
<div style="margin-top: 0.3em">
|
<div style="margin-top: 0.3em">
|
||||||
<div id="sharableLinkContainer" style="display: none">
|
<div id="sharableLinkContainer" style="display: none">
|
||||||
<a id="sharableLink" target="_blank"></a>
|
<a id="sharableLink" target="_blank"></a>
|
||||||
<i data-tip="Copy link to the clipboard" onclick="copyLinkToClickboard()" class="icon-clone pointer"></i>
|
<i id="copyLinkToClickboard" data-tip="Copy link to the clipboard" class="icon-clone pointer"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -7691,7 +7676,6 @@
|
||||||
<script type="module" src="/src/modules/ui/tools.js"></script>
|
<script type="module" src="/src/modules/ui/tools.js"></script>
|
||||||
<script type="module" src="/src/modules/ui/threeD.js"></script>
|
<script type="module" src="/src/modules/ui/threeD.js"></script>
|
||||||
<script type="module" src="/src/modules/ui/submap.js"></script>
|
<script type="module" src="/src/modules/ui/submap.js"></script>
|
||||||
<script type="module" src="/src/modules/ui/hotkeys.js"></script>
|
|
||||||
<script type="module" src="/src/modules/coa-renderer.js"></script>
|
<script type="module" src="/src/modules/coa-renderer.js"></script>
|
||||||
<script type="module" src="/src/modules/io/save.js"></script>
|
<script type="module" src="/src/modules/io/save.js"></script>
|
||||||
<script type="module" src="/src/modules/io/load.js"></script>
|
<script type="module" src="/src/modules/io/load.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {generateSeed} from "utils/probabilityUtils";
|
||||||
import {getColorScheme} from "utils/colorUtils";
|
import {getColorScheme} from "utils/colorUtils";
|
||||||
import {aleaPRNG} from "scripts/aleaPRNG";
|
import {aleaPRNG} from "scripts/aleaPRNG";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
|
import {regeneratePrompt} from "modules/ui/options";
|
||||||
|
|
||||||
const initialSeed = generateSeed();
|
const initialSeed = generateSeed();
|
||||||
let graph = getGraph(grid);
|
let graph = getGraph(grid);
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ export function addDragToUpload() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function quickLoad() {
|
export function quickLoad() {
|
||||||
ldb.get("lastMap", blob => {
|
ldb.get("lastMap", blob => {
|
||||||
if (blob) {
|
if (blob) {
|
||||||
loadMapPrompt(blob);
|
loadMapPrompt(blob);
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ function getMapData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download .map file
|
// Download .map file
|
||||||
function dowloadMap() {
|
export function dowloadMap() {
|
||||||
if (customization)
|
if (customization)
|
||||||
return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error");
|
return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error");
|
||||||
closeDialogs("#alert");
|
closeDialogs("#alert");
|
||||||
|
|
@ -142,7 +142,7 @@ function dowloadMap() {
|
||||||
window.URL.revokeObjectURL(URL);
|
window.URL.revokeObjectURL(URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveToDropbox() {
|
export async function saveToDropbox() {
|
||||||
if (customization)
|
if (customization)
|
||||||
return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error");
|
return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error");
|
||||||
closeDialogs("#alert");
|
closeDialogs("#alert");
|
||||||
|
|
@ -157,7 +157,7 @@ async function saveToDropbox() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function quickSave() {
|
export function quickSave() {
|
||||||
if (customization)
|
if (customization)
|
||||||
return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error");
|
return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error");
|
||||||
|
|
||||||
|
|
@ -189,7 +189,7 @@ const saveReminder = function () {
|
||||||
};
|
};
|
||||||
saveReminder();
|
saveReminder();
|
||||||
|
|
||||||
function toggleSaveReminder() {
|
export function toggleSaveReminder() {
|
||||||
if (saveReminder.status) {
|
if (saveReminder.status) {
|
||||||
tip("Save reminder is turned off. Press CTRL+Q again to re-initiate", true, "warn", 2000);
|
tip("Save reminder is turned off. Press CTRL+Q again to re-initiate", true, "warn", 2000);
|
||||||
clearInterval(saveReminder.reminder);
|
clearInterval(saveReminder.reminder);
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,26 @@
|
||||||
import {openDialog} from "dialogs";
|
import {openDialog} from "dialogs";
|
||||||
import {toggleLayer} from "layers";
|
import {toggleLayer} from "layers";
|
||||||
|
// @ts-expect-error js module
|
||||||
import {showAboutDialog} from "scripts/options/about";
|
import {showAboutDialog} from "scripts/options/about";
|
||||||
import {byId} from "utils/shorthands";
|
import {byId} from "utils/shorthands";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
|
import {minmax} from "utils/numberUtils";
|
||||||
|
// @ts-expect-error js module
|
||||||
|
import {hideOptions} from "modules/ui/options";
|
||||||
|
// @ts-expect-error js module
|
||||||
|
import {regeneratePrompt, toggle3dOptions, toggleOptions} from "modules/ui/options";
|
||||||
|
// @ts-expect-error js module
|
||||||
|
import {quickSave, saveToDropbox, dowloadMap, toggleSaveReminder} from "modules/io/save";
|
||||||
|
// @ts-expect-error js module
|
||||||
|
import {quickLoad} from "modules/io/load";
|
||||||
|
|
||||||
// Hotkeys, see github.com/Azgaar/Fantasy-Map-Generator/wiki/Hotkeys
|
// Hotkeys, see github.com/Azgaar/Fantasy-Map-Generator/wiki/Hotkeys
|
||||||
document.on("keydown", handleKeydown);
|
export function addHotkeyListeners() {
|
||||||
document.on("keyup", handleKeyup);
|
document.on("keydown", handleKeydown as EventListener);
|
||||||
|
document.on("keyup", handleKeyup as EventListener);
|
||||||
|
}
|
||||||
|
|
||||||
function handleKeydown(event) {
|
function handleKeydown(event: KeyboardEvent) {
|
||||||
if (!allowHotkeys()) return; // in some cases (e.g. in a textarea) hotkeys are not allowed
|
if (!allowHotkeys()) return; // in some cases (e.g. in a textarea) hotkeys are not allowed
|
||||||
|
|
||||||
const {code, ctrlKey, altKey} = event;
|
const {code, ctrlKey, altKey} = event;
|
||||||
|
|
@ -17,7 +29,7 @@ function handleKeydown(event) {
|
||||||
if (["F1", "F2", "F6", "F9", "Tab"].includes(code)) event.preventDefault(); // disallow default Fn and Tab
|
if (["F1", "F2", "F6", "F9", "Tab"].includes(code)) event.preventDefault(); // disallow default Fn and Tab
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeyup(event) {
|
function handleKeyup(event: KeyboardEvent) {
|
||||||
if (!allowHotkeys()) return; // in some cases (e.g. in a textarea) hotkeys are not allowed
|
if (!allowHotkeys()) return; // in some cases (e.g. in a textarea) hotkeys are not allowed
|
||||||
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
@ -27,6 +39,10 @@ function handleKeyup(event) {
|
||||||
const shift = shiftKey || key === "Shift";
|
const shift = shiftKey || key === "Shift";
|
||||||
const alt = altKey || key === "Alt";
|
const alt = altKey || key === "Alt";
|
||||||
|
|
||||||
|
const Zoom = window.Zoom;
|
||||||
|
const $undo = byId("undo");
|
||||||
|
const $redo = byId("redo");
|
||||||
|
|
||||||
if (code === "F1") showAboutDialog();
|
if (code === "F1") showAboutDialog();
|
||||||
else if (code === "F2") regeneratePrompt();
|
else if (code === "F2") regeneratePrompt();
|
||||||
else if (code === "F6") quickSave();
|
else if (code === "F6") quickSave();
|
||||||
|
|
@ -38,8 +54,8 @@ function handleKeyup(event) {
|
||||||
else if (ctrl && code === "KeyQ") toggleSaveReminder();
|
else if (ctrl && code === "KeyQ") toggleSaveReminder();
|
||||||
else if (ctrl && code === "KeyS") dowloadMap();
|
else if (ctrl && code === "KeyS") dowloadMap();
|
||||||
else if (ctrl && code === "KeyC") saveToDropbox();
|
else if (ctrl && code === "KeyC") saveToDropbox();
|
||||||
else if (ctrl && code === "KeyZ" && undo?.offsetParent) undo.click();
|
else if (ctrl && code === "KeyZ" && $undo?.offsetParent) $undo.click();
|
||||||
else if (ctrl && code === "KeyY" && redo?.offsetParent) redo.click();
|
else if (ctrl && code === "KeyY" && $redo?.offsetParent) $redo.click();
|
||||||
else if (shift && code === "KeyH") openDialog("heightmapEditor");
|
else if (shift && code === "KeyH") openDialog("heightmapEditor");
|
||||||
else if (shift && code === "KeyB") editBiomes();
|
else if (shift && code === "KeyB") editBiomes();
|
||||||
else if (shift && code === "KeyS") openDialog("statesEditor");
|
else if (shift && code === "KeyS") openDialog("statesEditor");
|
||||||
|
|
@ -95,70 +111,80 @@ function handleKeyup(event) {
|
||||||
else if (code === "KeyK") toggleLayer("toggleMarkers");
|
else if (code === "KeyK") toggleLayer("toggleMarkers");
|
||||||
else if (code === "Equal") toggleLayer("toggleRulers");
|
else if (code === "Equal") toggleLayer("toggleRulers");
|
||||||
else if (code === "Slash") toggleLayer("toggleScaleBar");
|
else if (code === "Slash") toggleLayer("toggleScaleBar");
|
||||||
else if (code === "ArrowLeft") zoom.translateBy(svg, 10, 0);
|
else if (code === "ArrowLeft") Zoom.translateBy(svg, 10, 0);
|
||||||
else if (code === "ArrowRight") zoom.translateBy(svg, -10, 0);
|
else if (code === "ArrowRight") Zoom.translateBy(svg, -10, 0);
|
||||||
else if (code === "ArrowUp") zoom.translateBy(svg, 0, 10);
|
else if (code === "ArrowUp") Zoom.translateBy(svg, 0, 10);
|
||||||
else if (code === "ArrowDown") zoom.translateBy(svg, 0, -10);
|
else if (code === "ArrowDown") Zoom.translateBy(svg, 0, -10);
|
||||||
else if (key === "+" || key === "-") pressNumpadSign(key);
|
else if (key === "+" || key === "-") pressNumpadSign(key);
|
||||||
else if (key === "0") Zoom.reset(1000);
|
else if (key === "0") Zoom.reset(1000);
|
||||||
else if (key === "1") zoom.scaleTo(svg, 1);
|
else if (key === "1") Zoom.scaleTo(svg, 1);
|
||||||
else if (key === "2") zoom.scaleTo(svg, 2);
|
else if (key === "2") Zoom.scaleTo(svg, 2);
|
||||||
else if (key === "3") zoom.scaleTo(svg, 3);
|
else if (key === "3") Zoom.scaleTo(svg, 3);
|
||||||
else if (key === "4") zoom.scaleTo(svg, 4);
|
else if (key === "4") Zoom.scaleTo(svg, 4);
|
||||||
else if (key === "5") zoom.scaleTo(svg, 5);
|
else if (key === "5") Zoom.scaleTo(svg, 5);
|
||||||
else if (key === "6") zoom.scaleTo(svg, 6);
|
else if (key === "6") Zoom.scaleTo(svg, 6);
|
||||||
else if (key === "7") zoom.scaleTo(svg, 7);
|
else if (key === "7") Zoom.scaleTo(svg, 7);
|
||||||
else if (key === "8") zoom.scaleTo(svg, 8);
|
else if (key === "8") Zoom.scaleTo(svg, 8);
|
||||||
else if (key === "9") zoom.scaleTo(svg, 9);
|
else if (key === "9") Zoom.scaleTo(svg, 9);
|
||||||
else if (ctrl) toggleMode();
|
else if (ctrl) toggleMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
function allowHotkeys() {
|
function allowHotkeys() {
|
||||||
const {tagName, contentEditable} = document.activeElement;
|
if (document.activeElement) {
|
||||||
if (["INPUT", "SELECT", "TEXTAREA"].includes(tagName)) return false;
|
const {tagName, contentEditable} = document.activeElement as HTMLElement;
|
||||||
if (tagName === "DIV" && contentEditable === "true") return false;
|
if (["INPUT", "SELECT", "TEXTAREA"].includes(tagName)) return false;
|
||||||
if (document.getSelection().toString()) return false;
|
if (tagName === "DIV" && contentEditable === "true") return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.getSelection()?.toString()) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pressNumpadSign(key) {
|
function getActionBrushInput() {
|
||||||
const change = key === "+" ? 1 : -1;
|
if (byId("brushRadius")?.offsetParent) return byId("brushRadius");
|
||||||
let brush = null;
|
if (byId("biomesManuallyBrush")?.offsetParent) return byId("biomesManuallyBrush");
|
||||||
|
if (byId("statesManuallyBrush")?.offsetParent) return byId("statesManuallyBrush");
|
||||||
if (byId("brushRadius")?.offsetParent) brush = byId("brushRadius");
|
if (byId("provincesManuallyBrush")?.offsetParent) return byId("provincesManuallyBrush");
|
||||||
else if (byId("biomesManuallyBrush")?.offsetParent) brush = byId("biomesManuallyBrush");
|
if (byId("culturesManuallyBrush")?.offsetParent) return byId("culturesManuallyBrush");
|
||||||
else if (byId("statesManuallyBrush")?.offsetParent) brush = byId("statesManuallyBrush");
|
if (byId("zonesBrush")?.offsetParent) return byId("zonesBrush");
|
||||||
else if (byId("provincesManuallyBrush")?.offsetParent) brush = byId("provincesManuallyBrush");
|
if (byId("religionsManuallyBrush")?.offsetParent) return byId("religionsManuallyBrush");
|
||||||
else if (byId("culturesManuallyBrush")?.offsetParent) brush = byId("culturesManuallyBrush");
|
return null;
|
||||||
else if (byId("zonesBrush")?.offsetParent) brush = byId("zonesBrush");
|
}
|
||||||
else if (byId("religionsManuallyBrush")?.offsetParent) brush = byId("religionsManuallyBrush");
|
|
||||||
|
|
||||||
|
function pressNumpadSign(key: "+" | "-") {
|
||||||
|
const brush = getActionBrushInput() as HTMLInputElement | null;
|
||||||
if (brush) {
|
if (brush) {
|
||||||
const value = minmax(+brush.value + change, +brush.min, +brush.max);
|
const change = key === "+" ? 1 : -1;
|
||||||
brush.value = byId(brush.id + "Number").value = value;
|
const value = String(minmax(+brush.value + change, +brush.min, +brush.max));
|
||||||
return;
|
brush.value = value;
|
||||||
}
|
|
||||||
|
|
||||||
const scaleBy = key === "+" ? 1.2 : 0.8;
|
const numberInput = byId(brush.id + "Number") as HTMLInputElement | null;
|
||||||
zoom.scaleBy(svg, scaleBy); // if no brush elements displayed, zoom map
|
if (numberInput) numberInput.value = value;
|
||||||
|
} else {
|
||||||
|
// if no brush inputs visible, Zoom map
|
||||||
|
const scaleBy = key === "+" ? 1.2 : 0.8;
|
||||||
|
window.Zoom.scaleBy(svg, scaleBy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleMode() {
|
function toggleMode() {
|
||||||
if (zonesRemove?.offsetParent) {
|
const $zonesRemove = byId("zonesRemove");
|
||||||
zonesRemove.classList.contains("pressed")
|
if ($zonesRemove?.offsetParent) {
|
||||||
? zonesRemove.classList.remove("pressed")
|
$zonesRemove.classList.contains("pressed")
|
||||||
: zonesRemove.classList.add("pressed");
|
? $zonesRemove.classList.remove("pressed")
|
||||||
|
: $zonesRemove.classList.add("pressed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeElementOnKey() {
|
function removeElementOnKey() {
|
||||||
const fastDelete = Array.from(document.querySelectorAll("[role='dialog'] .fastDelete")).find(
|
const dialogsWithFastDelete = document.querySelectorAll("[role='dialog'] .fastDelete");
|
||||||
dialog => dialog.style.display !== "none"
|
const $fastDelete = Array.from(dialogsWithFastDelete).find(
|
||||||
);
|
dialog => (dialog as HTMLElement).style.display !== "none"
|
||||||
if (fastDelete) fastDelete.click();
|
) as HTMLElement | undefined;
|
||||||
|
if ($fastDelete) $fastDelete.click();
|
||||||
|
|
||||||
const visibleDialogs = Array.from(document.querySelectorAll("[role='dialog']")).filter(
|
const visibleDialogs = Array.from(document.querySelectorAll("[role='dialog']")).filter(
|
||||||
dialog => dialog.style.display !== "none"
|
dialog => (dialog as HTMLElement).style.display !== "none"
|
||||||
);
|
);
|
||||||
if (!visibleDialogs.length) return;
|
if (!visibleDialogs.length) return;
|
||||||
|
|
||||||
|
|
@ -13,6 +13,7 @@ import {regenerateMap} from "scripts/generation";
|
||||||
import {fitScaleBar} from "modules/measurers";
|
import {fitScaleBar} from "modules/measurers";
|
||||||
import {openDialog} from "dialogs";
|
import {openDialog} from "dialogs";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
|
import {quickSave, saveToDropbox, dowloadMap} from "modules/io/save.js";
|
||||||
|
|
||||||
$("#optionsContainer").draggable({handle: ".drag-trigger", snap: "svg", snapMode: "both"});
|
$("#optionsContainer").draggable({handle: ".drag-trigger", snap: "svg", snapMode: "both"});
|
||||||
$("#exitCustomization").draggable({handle: "div"});
|
$("#exitCustomization").draggable({handle: "div"});
|
||||||
|
|
@ -33,32 +34,32 @@ function showOptions(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
regenerate.style.display = "none";
|
regenerate.style.display = "none";
|
||||||
document.getElementById("options").style.display = "block";
|
byId("options").style.display = "block";
|
||||||
optionsTrigger.style.display = "none";
|
optionsTrigger.style.display = "none";
|
||||||
|
|
||||||
if (event) event.stopPropagation();
|
if (event) event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide options pane on trigger click
|
// Hide options pane on trigger click
|
||||||
function hideOptions(event) {
|
export function hideOptions(event) {
|
||||||
document.getElementById("options").style.display = "none";
|
byId("options").style.display = "none";
|
||||||
optionsTrigger.style.display = "block";
|
optionsTrigger.style.display = "block";
|
||||||
if (event) event.stopPropagation();
|
if (event) event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// To toggle options on hotkey press
|
// To toggle options on hotkey press
|
||||||
function toggleOptions(event) {
|
export function toggleOptions(event) {
|
||||||
if (document.getElementById("options").style.display === "none") showOptions(event);
|
if (byId("options").style.display === "none") showOptions(event);
|
||||||
else hideOptions(event);
|
else hideOptions(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle "New Map!" pane on hover
|
// Toggle "New Map!" pane on hover
|
||||||
optionsTrigger.addEventListener("mouseenter", function () {
|
optionsTrigger.on("mouseenter", function () {
|
||||||
if (optionsTrigger.classList.contains("glow")) return;
|
if (optionsTrigger.classList.contains("glow")) return;
|
||||||
if (document.getElementById("options").style.display === "none") regenerate.style.display = "block";
|
if (byId("options").style.display === "none") regenerate.style.display = "block";
|
||||||
});
|
});
|
||||||
|
|
||||||
collapsible.addEventListener("mouseleave", function () {
|
collapsible.on("mouseleave", function () {
|
||||||
regenerate.style.display = "none";
|
regenerate.style.display = "none";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -66,14 +67,14 @@ collapsible.addEventListener("mouseleave", function () {
|
||||||
document
|
document
|
||||||
.getElementById("options")
|
.getElementById("options")
|
||||||
.querySelector("div.tab")
|
.querySelector("div.tab")
|
||||||
.addEventListener("click", function (event) {
|
.on("click", function (event) {
|
||||||
if (event.target.tagName !== "BUTTON") return;
|
if (event.target.tagName !== "BUTTON") return;
|
||||||
const id = event.target.id;
|
const id = event.target.id;
|
||||||
const active = document.getElementById("options").querySelector(".tab > button.active");
|
const active = byId("options").querySelector(".tab > button.active");
|
||||||
if (active && id === active.id) return; // already active tab is clicked
|
if (active && id === active.id) return; // already active tab is clicked
|
||||||
|
|
||||||
if (active) active.classList.remove("active");
|
if (active) active.classList.remove("active");
|
||||||
document.getElementById(id).classList.add("active");
|
byId(id).classList.add("active");
|
||||||
document
|
document
|
||||||
.getElementById("options")
|
.getElementById("options")
|
||||||
.querySelectorAll(".tabcontent")
|
.querySelectorAll(".tabcontent")
|
||||||
|
|
@ -101,10 +102,10 @@ async function showSupporters() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// on any option or dialog change
|
// on any option or dialog change
|
||||||
document.getElementById("options").addEventListener("change", storeValueIfRequired);
|
byId("options").on("change", storeValueIfRequired);
|
||||||
document.getElementById("dialogs").addEventListener("change", storeValueIfRequired);
|
byId("dialogs").on("change", storeValueIfRequired);
|
||||||
document.getElementById("options").addEventListener("input", updateOutputToFollowInput);
|
byId("options").on("input", updateOutputToFollowInput);
|
||||||
document.getElementById("dialogs").addEventListener("input", updateOutputToFollowInput);
|
byId("dialogs").on("input", updateOutputToFollowInput);
|
||||||
|
|
||||||
function storeValueIfRequired(ev) {
|
function storeValueIfRequired(ev) {
|
||||||
if (ev.target.dataset.stored) lock(ev.target.dataset.stored);
|
if (ev.target.dataset.stored) lock(ev.target.dataset.stored);
|
||||||
|
|
@ -119,17 +120,17 @@ function updateOutputToFollowInput(ev) {
|
||||||
|
|
||||||
// generic case
|
// generic case
|
||||||
if (id.slice(-5) === "Input") {
|
if (id.slice(-5) === "Input") {
|
||||||
const output = document.getElementById(id.slice(0, -5) + "Output");
|
const output = byId(id.slice(0, -5) + "Output");
|
||||||
if (output) output.value = value;
|
if (output) output.value = value;
|
||||||
} else if (id.slice(-6) === "Output") {
|
} else if (id.slice(-6) === "Output") {
|
||||||
const input = document.getElementById(id.slice(0, -6) + "Input");
|
const input = byId(id.slice(0, -6) + "Input");
|
||||||
if (input) input.value = value;
|
if (input) input.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option listeners
|
// Option listeners
|
||||||
const optionsContent = document.getElementById("optionsContent");
|
const optionsContent = byId("optionsContent");
|
||||||
optionsContent.addEventListener("input", function (event) {
|
optionsContent.on("input", function (event) {
|
||||||
const id = event.target.id;
|
const id = event.target.id;
|
||||||
const value = event.target.value;
|
const value = event.target.value;
|
||||||
if (id === "mapWidthInput" || id === "mapHeightInput") mapSizeInputChange();
|
if (id === "mapWidthInput" || id === "mapHeightInput") mapSizeInputChange();
|
||||||
|
|
@ -143,7 +144,7 @@ optionsContent.addEventListener("input", function (event) {
|
||||||
else if (id === "transparencyInput") changeDialogsTheme(themeColorInput.value, value);
|
else if (id === "transparencyInput") changeDialogsTheme(themeColorInput.value, value);
|
||||||
});
|
});
|
||||||
|
|
||||||
optionsContent.addEventListener("change", function (event) {
|
optionsContent.on("change", function (event) {
|
||||||
const id = event.target.id;
|
const id = event.target.id;
|
||||||
const value = event.target.value;
|
const value = event.target.value;
|
||||||
|
|
||||||
|
|
@ -156,7 +157,7 @@ optionsContent.addEventListener("change", function (event) {
|
||||||
else if (id === "stateLabelsModeInput") options.stateLabelsMode = value;
|
else if (id === "stateLabelsModeInput") options.stateLabelsMode = value;
|
||||||
});
|
});
|
||||||
|
|
||||||
optionsContent.addEventListener("click", function (event) {
|
optionsContent.on("click", function (event) {
|
||||||
const id = event.target.id;
|
const id = event.target.id;
|
||||||
if (id === "toggleFullscreen") toggleFullscreen();
|
if (id === "toggleFullscreen") toggleFullscreen();
|
||||||
else if (id === "optionsMapHistory") showSeedHistoryDialog();
|
else if (id === "optionsMapHistory") showSeedHistoryDialog();
|
||||||
|
|
@ -252,7 +253,7 @@ const voiceInterval = setInterval(function () {
|
||||||
if (voices.length) clearInterval(voiceInterval);
|
if (voices.length) clearInterval(voiceInterval);
|
||||||
else return;
|
else return;
|
||||||
|
|
||||||
const select = document.getElementById("speakerVoice");
|
const select = byId("speakerVoice");
|
||||||
voices.forEach((voice, i) => {
|
voices.forEach((voice, i) => {
|
||||||
select.options.add(new Option(voice.name, i, false));
|
select.options.add(new Option(voice.name, i, false));
|
||||||
});
|
});
|
||||||
|
|
@ -266,7 +267,7 @@ function testSpeaker() {
|
||||||
const speaker = new SpeechSynthesisUtterance(text);
|
const speaker = new SpeechSynthesisUtterance(text);
|
||||||
const voices = speechSynthesis.getVoices();
|
const voices = speechSynthesis.getVoices();
|
||||||
if (voices.length) {
|
if (voices.length) {
|
||||||
const voiceId = +document.getElementById("speakerVoice").value;
|
const voiceId = +byId("speakerVoice").value;
|
||||||
speaker.voice = voices[voiceId];
|
speaker.voice = voices[voiceId];
|
||||||
}
|
}
|
||||||
speechSynthesis.speak(speaker);
|
speechSynthesis.speak(speaker);
|
||||||
|
|
@ -366,7 +367,7 @@ function changeCultureSet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeEmblemShape(emblemShape) {
|
function changeEmblemShape(emblemShape) {
|
||||||
const image = document.getElementById("emblemShapeImage");
|
const image = byId("emblemShapeImage");
|
||||||
const shapePath = window.COArenderer && COArenderer.shieldPaths[emblemShape];
|
const shapePath = window.COArenderer && COArenderer.shieldPaths[emblemShape];
|
||||||
shapePath ? image.setAttribute("d", shapePath) : image.removeAttribute("d");
|
shapePath ? image.setAttribute("d", shapePath) : image.removeAttribute("d");
|
||||||
|
|
||||||
|
|
@ -375,7 +376,7 @@ function changeEmblemShape(emblemShape) {
|
||||||
pack.cultures.filter(c => !c.removed).forEach(c => (c.shield = Cultures.getRandomShield()));
|
pack.cultures.filter(c => !c.removed).forEach(c => (c.shield = Cultures.getRandomShield()));
|
||||||
|
|
||||||
const rerenderCOA = (id, coa) => {
|
const rerenderCOA = (id, coa) => {
|
||||||
const coaEl = document.getElementById(id);
|
const coaEl = byId(id);
|
||||||
if (!coaEl) return; // not rendered
|
if (!coaEl) return; // not rendered
|
||||||
coaEl.remove();
|
coaEl.remove();
|
||||||
COArenderer.trigger(id, coa);
|
COArenderer.trigger(id, coa);
|
||||||
|
|
@ -421,7 +422,7 @@ function changeUIsize(value) {
|
||||||
|
|
||||||
uiSizeInput.value = uiSizeOutput.value = value;
|
uiSizeInput.value = uiSizeOutput.value = value;
|
||||||
document.getElementsByTagName("body")[0].style.fontSize = rn(value * 10, 2) + "px";
|
document.getElementsByTagName("body")[0].style.fontSize = rn(value * 10, 2) + "px";
|
||||||
document.getElementById("options").style.width = value * 300 + "px";
|
byId("options").style.width = value * 300 + "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUImaxSize() {
|
function getUImaxSize() {
|
||||||
|
|
@ -659,7 +660,7 @@ function restoreDefaultOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sticked menu Options listeners
|
// Sticked menu Options listeners
|
||||||
document.getElementById("sticked").addEventListener("click", function (event) {
|
byId("sticked").on("click", function (event) {
|
||||||
const id = event.target.id;
|
const id = event.target.id;
|
||||||
if (id === "newMapButton") regeneratePrompt();
|
if (id === "newMapButton") regeneratePrompt();
|
||||||
else if (id === "saveButton") showSavePane();
|
else if (id === "saveButton") showSavePane();
|
||||||
|
|
@ -668,7 +669,9 @@ document.getElementById("sticked").addEventListener("click", function (event) {
|
||||||
else if (id === "zoomReset") Zoom.reset(1000);
|
else if (id === "zoomReset") Zoom.reset(1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
function regeneratePrompt(options) {
|
byId("regenerate").on("click", regeneratePrompt);
|
||||||
|
|
||||||
|
export function regeneratePrompt(options) {
|
||||||
if (customization)
|
if (customization)
|
||||||
return tip("New map cannot be generated when edit mode is active, please exit the mode and retry", false, "error");
|
return tip("New map cannot be generated when edit mode is active, please exit the mode and retry", false, "error");
|
||||||
const workingTime = (Date.now() - last(mapHistory).created) / 60000; // minutes
|
const workingTime = (Date.now() - last(mapHistory).created) / 60000; // minutes
|
||||||
|
|
@ -692,7 +695,7 @@ function regeneratePrompt(options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSavePane() {
|
function showSavePane() {
|
||||||
const sharableLinkContainer = document.getElementById("sharableLinkContainer");
|
const sharableLinkContainer = byId("sharableLinkContainer");
|
||||||
sharableLinkContainer.style.display = "none";
|
sharableLinkContainer.style.display = "none";
|
||||||
|
|
||||||
$("#saveMapData").dialog({
|
$("#saveMapData").dialog({
|
||||||
|
|
@ -708,14 +711,18 @@ function showSavePane() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byId("dowloadMap").on("click", dowloadMap);
|
||||||
|
byId("saveToDropbox").on("click", saveToDropbox);
|
||||||
|
byId("quickSave").on("click", quickSave);
|
||||||
|
|
||||||
function copyLinkToClickboard() {
|
function copyLinkToClickboard() {
|
||||||
const shrableLink = document.getElementById("sharableLink");
|
const shrableLink = byId("sharableLink");
|
||||||
const link = shrableLink.getAttribute("href");
|
const link = shrableLink.getAttribute("href");
|
||||||
navigator.clipboard.writeText(link).then(() => tip("Link is copied to the clipboard", true, "success", 8000));
|
navigator.clipboard.writeText(link).then(() => tip("Link is copied to the clipboard", true, "success", 8000));
|
||||||
}
|
}
|
||||||
|
|
||||||
function showExportPane() {
|
function showExportPane() {
|
||||||
document.getElementById("showLabels").checked = !hideLabels.checked;
|
byId("showLabels").checked = !hideLabels.checked;
|
||||||
|
|
||||||
$("#exportMapData").dialog({
|
$("#exportMapData").dialog({
|
||||||
title: "Export map data",
|
title: "Export map data",
|
||||||
|
|
@ -735,6 +742,21 @@ async function exportToJson(type) {
|
||||||
exportToJson(type);
|
exportToJson(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byId("saveSVG").on("click", saveSVG);
|
||||||
|
byId("savePNG").on("click", savePNG);
|
||||||
|
byId("saveJPEG").on("click", saveJPEG);
|
||||||
|
byId("openSaveTiles").on("click", openSaveTiles);
|
||||||
|
|
||||||
|
byId("saveGeoJSON_Cells").on("click", saveGeoJSON_Cells);
|
||||||
|
byId("saveGeoJSON_Routes").on("click", saveGeoJSON_Routes);
|
||||||
|
byId("saveGeoJSON_Rivers").on("click", saveGeoJSON_Rivers);
|
||||||
|
byId("saveGeoJSON_Markers").on("click", saveGeoJSON_Markers);
|
||||||
|
|
||||||
|
byId("exportToJson_Full").on("click", () => exportToJson("Full"));
|
||||||
|
byId("exportToJson_Minimal").on("click", () => exportToJson("Minimal"));
|
||||||
|
byId("exportToJson_PackCells").on("click", () => exportToJson("PackCells"));
|
||||||
|
byId("exportToJson_GridCells").on("click", () => exportToJson("GridCells"));
|
||||||
|
|
||||||
async function showLoadPane() {
|
async function showLoadPane() {
|
||||||
$("#loadMapData").dialog({
|
$("#loadMapData").dialog({
|
||||||
title: "Load map",
|
title: "Load map",
|
||||||
|
|
@ -750,10 +772,10 @@ async function showLoadPane() {
|
||||||
|
|
||||||
// already connected to Dropbox: list saved maps
|
// already connected to Dropbox: list saved maps
|
||||||
if (Cloud.providers.dropbox.api) {
|
if (Cloud.providers.dropbox.api) {
|
||||||
document.getElementById("dropboxConnectButton").style.display = "none";
|
byId("dropboxConnectButton").style.display = "none";
|
||||||
document.getElementById("loadFromDropboxSelect").style.display = "block";
|
byId("loadFromDropboxSelect").style.display = "block";
|
||||||
const loadFromDropboxButtons = document.getElementById("loadFromDropboxButtons");
|
const loadFromDropboxButtons = byId("loadFromDropboxButtons");
|
||||||
const fileSelect = document.getElementById("loadFromDropboxSelect");
|
const fileSelect = byId("loadFromDropboxSelect");
|
||||||
fileSelect.innerHTML = /* html */ `<option value="" disabled selected>Loading...</option>`;
|
fileSelect.innerHTML = /* html */ `<option value="" disabled selected>Loading...</option>`;
|
||||||
|
|
||||||
const files = await Cloud.providers.dropbox.list();
|
const files = await Cloud.providers.dropbox.list();
|
||||||
|
|
@ -778,11 +800,20 @@ async function showLoadPane() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// not connected to Dropbox: show connect button
|
// not connected to Dropbox: show connect button
|
||||||
document.getElementById("dropboxConnectButton").style.display = "inline-block";
|
byId("dropboxConnectButton").style.display = "inline-block";
|
||||||
document.getElementById("loadFromDropboxButtons").style.display = "none";
|
byId("loadFromDropboxButtons").style.display = "none";
|
||||||
document.getElementById("loadFromDropboxSelect").style.display = "none";
|
byId("loadFromDropboxSelect").style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byId("loadFromMachine").on("click", () => mapToLoad.click());
|
||||||
|
byId("loadURL").on("click", loadURL);
|
||||||
|
byId("quickLoad").on("click", quickLoad);
|
||||||
|
|
||||||
|
byId("dropboxConnectButton").on("click", connectToDropbox);
|
||||||
|
byId("loadFromDropbox").on("click", loadFromDropbox);
|
||||||
|
byId("createSharableDropboxLink").on("click", createSharableDropboxLink);
|
||||||
|
byId("copyLinkToClickboard").on("click", copyLinkToClickboard);
|
||||||
|
|
||||||
async function connectToDropbox() {
|
async function connectToDropbox() {
|
||||||
await Cloud.providers.dropbox.initialize();
|
await Cloud.providers.dropbox.initialize();
|
||||||
if (Cloud.providers.dropbox.api) showLoadPane();
|
if (Cloud.providers.dropbox.api) showLoadPane();
|
||||||
|
|
@ -816,7 +847,7 @@ function loadURL() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// load map
|
// load map
|
||||||
document.getElementById("mapToLoad").addEventListener("change", function () {
|
byId("mapToLoad").on("change", function () {
|
||||||
const fileToLoad = this.files[0];
|
const fileToLoad = this.files[0];
|
||||||
this.value = "";
|
this.value = "";
|
||||||
closeDialogs();
|
closeDialogs();
|
||||||
|
|
@ -826,12 +857,12 @@ document.getElementById("mapToLoad").addEventListener("change", function () {
|
||||||
function openSaveTiles() {
|
function openSaveTiles() {
|
||||||
closeDialogs();
|
closeDialogs();
|
||||||
updateTilesOptions();
|
updateTilesOptions();
|
||||||
const status = document.getElementById("tileStatus");
|
const status = byId("tileStatus");
|
||||||
status.innerHTML = "";
|
status.innerHTML = "";
|
||||||
let loading = null;
|
let loading = null;
|
||||||
|
|
||||||
const inputs = document.getElementById("saveTilesScreen").querySelectorAll("input");
|
const inputs = byId("saveTilesScreen").querySelectorAll("input");
|
||||||
inputs.forEach(input => input.addEventListener("input", updateTilesOptions));
|
inputs.forEach(input => input.on("input", updateTilesOptions));
|
||||||
|
|
||||||
$("#saveTilesScreen").dialog({
|
$("#saveTilesScreen").dialog({
|
||||||
resizable: false,
|
resizable: false,
|
||||||
|
|
@ -867,10 +898,10 @@ function updateTilesOptions() {
|
||||||
if (prev?.tagName === "INPUT") prev.value = this.value;
|
if (prev?.tagName === "INPUT") prev.value = this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tileSize = document.getElementById("tileSize");
|
const tileSize = byId("tileSize");
|
||||||
const tilesX = +document.getElementById("tileColsOutput").value;
|
const tilesX = +byId("tileColsOutput").value;
|
||||||
const tilesY = +document.getElementById("tileRowsOutput").value;
|
const tilesY = +byId("tileRowsOutput").value;
|
||||||
const scale = +document.getElementById("tileScaleOutput").value;
|
const scale = +byId("tileScaleOutput").value;
|
||||||
|
|
||||||
// calculate size
|
// calculate size
|
||||||
const sizeX = graphWidth * scale * tilesX;
|
const sizeX = graphWidth * scale * tilesX;
|
||||||
|
|
@ -900,7 +931,7 @@ function updateTilesOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// View mode
|
// View mode
|
||||||
viewMode.addEventListener("click", changeViewMode);
|
viewMode.on("click", changeViewMode);
|
||||||
export function changeViewMode(event) {
|
export function changeViewMode(event) {
|
||||||
const button = event.target;
|
const button = event.target;
|
||||||
if (button.tagName !== "BUTTON") return;
|
if (button.tagName !== "BUTTON") return;
|
||||||
|
|
@ -919,9 +950,9 @@ function enterStandardView() {
|
||||||
heightmap3DView.classList.remove("pressed");
|
heightmap3DView.classList.remove("pressed");
|
||||||
viewStandard.classList.add("pressed");
|
viewStandard.classList.add("pressed");
|
||||||
|
|
||||||
if (!document.getElementById("canvas3d")) return;
|
if (!byId("canvas3d")) return;
|
||||||
ThreeD.stop();
|
ThreeD.stop();
|
||||||
document.getElementById("canvas3d").remove();
|
byId("canvas3d").remove();
|
||||||
if (options3dUpdate.offsetParent) $("#options3d").dialog("close");
|
if (options3dUpdate.offsetParent) $("#options3d").dialog("close");
|
||||||
if (preview3d.offsetParent) $("#preview3d").dialog("close");
|
if (preview3d.offsetParent) $("#preview3d").dialog("close");
|
||||||
}
|
}
|
||||||
|
|
@ -954,7 +985,7 @@ async function enter3dView(type) {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (type === "heightmap3DView") {
|
if (type === "heightmap3DView") {
|
||||||
document.getElementById("preview3d").appendChild(canvas);
|
byId("preview3d").appendChild(canvas);
|
||||||
$("#preview3d").dialog({
|
$("#preview3d").dialog({
|
||||||
title: "3D Preview",
|
title: "3D Preview",
|
||||||
resizable: true,
|
resizable: true,
|
||||||
|
|
@ -968,7 +999,7 @@ async function enter3dView(type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function resize3d() {
|
function resize3d() {
|
||||||
const canvas = document.getElementById("canvas3d");
|
const canvas = byId("canvas3d");
|
||||||
canvas.width = parseFloat(preview3d.style.width);
|
canvas.width = parseFloat(preview3d.style.width);
|
||||||
canvas.height = parseFloat(preview3d.style.height) - 2;
|
canvas.height = parseFloat(preview3d.style.height) - 2;
|
||||||
ThreeD.redraw();
|
ThreeD.redraw();
|
||||||
|
|
@ -976,7 +1007,7 @@ function resize3d() {
|
||||||
|
|
||||||
let isLoaded = false;
|
let isLoaded = false;
|
||||||
|
|
||||||
function toggle3dOptions() {
|
export function toggle3dOptions() {
|
||||||
if (options3dUpdate.offsetParent) {
|
if (options3dUpdate.offsetParent) {
|
||||||
$("#options3d").dialog("close");
|
$("#options3d").dialog("close");
|
||||||
return;
|
return;
|
||||||
|
|
@ -993,29 +1024,29 @@ function toggle3dOptions() {
|
||||||
if (isLoaded) return;
|
if (isLoaded) return;
|
||||||
isLoaded = true;
|
isLoaded = true;
|
||||||
|
|
||||||
document.getElementById("options3dUpdate").addEventListener("click", ThreeD.update);
|
byId("options3dUpdate").on("click", ThreeD.update);
|
||||||
document.getElementById("options3dSave").addEventListener("click", ThreeD.saveScreenshot);
|
byId("options3dSave").on("click", ThreeD.saveScreenshot);
|
||||||
document.getElementById("options3dOBJSave").addEventListener("click", ThreeD.saveOBJ);
|
byId("options3dOBJSave").on("click", ThreeD.saveOBJ);
|
||||||
|
|
||||||
document.getElementById("options3dScaleRange").addEventListener("input", changeHeightScale);
|
byId("options3dScaleRange").on("input", changeHeightScale);
|
||||||
document.getElementById("options3dScaleNumber").addEventListener("change", changeHeightScale);
|
byId("options3dScaleNumber").on("change", changeHeightScale);
|
||||||
document.getElementById("options3dLightnessRange").addEventListener("input", changeLightness);
|
byId("options3dLightnessRange").on("input", changeLightness);
|
||||||
document.getElementById("options3dLightnessNumber").addEventListener("change", changeLightness);
|
byId("options3dLightnessNumber").on("change", changeLightness);
|
||||||
document.getElementById("options3dSunX").addEventListener("change", changeSunPosition);
|
byId("options3dSunX").on("change", changeSunPosition);
|
||||||
document.getElementById("options3dSunY").addEventListener("change", changeSunPosition);
|
byId("options3dSunY").on("change", changeSunPosition);
|
||||||
document.getElementById("options3dSunZ").addEventListener("change", changeSunPosition);
|
byId("options3dSunZ").on("change", changeSunPosition);
|
||||||
document.getElementById("options3dMeshRotationRange").addEventListener("input", changeRotation);
|
byId("options3dMeshRotationRange").on("input", changeRotation);
|
||||||
document.getElementById("options3dMeshRotationNumber").addEventListener("change", changeRotation);
|
byId("options3dMeshRotationNumber").on("change", changeRotation);
|
||||||
document.getElementById("options3dGlobeRotationRange").addEventListener("input", changeRotation);
|
byId("options3dGlobeRotationRange").on("input", changeRotation);
|
||||||
document.getElementById("options3dGlobeRotationNumber").addEventListener("change", changeRotation);
|
byId("options3dGlobeRotationNumber").on("change", changeRotation);
|
||||||
document.getElementById("options3dMeshLabels3d").addEventListener("change", toggleLabels3d);
|
byId("options3dMeshLabels3d").on("change", toggleLabels3d);
|
||||||
document.getElementById("options3dMeshSkyMode").addEventListener("change", toggleSkyMode);
|
byId("options3dMeshSkyMode").on("change", toggleSkyMode);
|
||||||
document.getElementById("options3dMeshSky").addEventListener("input", changeColors);
|
byId("options3dMeshSky").on("input", changeColors);
|
||||||
document.getElementById("options3dMeshWater").addEventListener("input", changeColors);
|
byId("options3dMeshWater").on("input", changeColors);
|
||||||
document.getElementById("options3dGlobeResolution").addEventListener("change", changeResolution);
|
byId("options3dGlobeResolution").on("change", changeResolution);
|
||||||
|
|
||||||
function updateValues() {
|
function updateValues() {
|
||||||
const globe = document.getElementById("canvas3d").dataset.type === "viewGlobe";
|
const globe = byId("canvas3d").dataset.type === "viewGlobe";
|
||||||
options3dMesh.style.display = globe ? "none" : "block";
|
options3dMesh.style.display = globe ? "none" : "block";
|
||||||
options3dGlobe.style.display = globe ? "block" : "none";
|
options3dGlobe.style.display = globe ? "block" : "none";
|
||||||
options3dScaleRange.value = options3dScaleNumber.value = ThreeD.options.scale;
|
options3dScaleRange.value = options3dScaleNumber.value = ThreeD.options.scale;
|
||||||
|
|
|
||||||
|
|
@ -65,5 +65,9 @@ window.Zoom = (function () {
|
||||||
zoom.scaleTo(element, scale);
|
zoom.scaleTo(element, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {setZoomBehavior, invoke, force, to, reset, scaleExtent, translateExtent, scaleTo};
|
function translateBy(element, x, y) {
|
||||||
|
zoom.translateBy(element, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {setZoomBehavior, invoke, force, to, reset, scaleExtent, translateExtent, scaleTo, translateBy};
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import {assignSpeakerBehavior} from "./speaker";
|
||||||
import {addResizeListener} from "modules/ui/options";
|
import {addResizeListener} from "modules/ui/options";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import {addDragToUpload} from "modules/io/load";
|
import {addDragToUpload} from "modules/io/load";
|
||||||
|
import {addHotkeyListeners} from "modules/ui/hotkeys";
|
||||||
|
|
||||||
export function addGlobalListeners() {
|
export function addGlobalListeners() {
|
||||||
if (PRODUCTION) {
|
if (PRODUCTION) {
|
||||||
|
|
@ -18,6 +19,7 @@ export function addGlobalListeners() {
|
||||||
assignLockBehavior();
|
assignLockBehavior();
|
||||||
addTooptipListers();
|
addTooptipListers();
|
||||||
addResizeListener();
|
addResizeListener();
|
||||||
|
addHotkeyListeners();
|
||||||
assignSpeakerBehavior();
|
assignSpeakerBehavior();
|
||||||
addDragToUpload();
|
addDragToUpload();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7
src/types/pack.d.ts
vendored
7
src/types/pack.d.ts
vendored
|
|
@ -1,9 +1,12 @@
|
||||||
|
import {Numeric} from "d3";
|
||||||
|
|
||||||
interface IPack {
|
interface IPack {
|
||||||
vertices: {
|
vertices: {
|
||||||
p: TPoints;
|
p: TPoints;
|
||||||
v: number[][];
|
v: number[][];
|
||||||
c: number[][];
|
c: number[][];
|
||||||
};
|
};
|
||||||
|
features: IFeature[];
|
||||||
cells: {
|
cells: {
|
||||||
i: IntArray;
|
i: IntArray;
|
||||||
p: TPoints;
|
p: TPoints;
|
||||||
|
|
@ -23,6 +26,10 @@ interface IPack {
|
||||||
religions: IReligion[];
|
religions: IReligion[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IFeature {
|
||||||
|
i: Numeric;
|
||||||
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
i: number;
|
i: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue