From cd5da954f0c184d353d14917ea403938aa613ce7 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Wed, 11 May 2022 18:05:59 -0500 Subject: [PATCH] Pull most of the code from the DOMContentLoaded event and put it into functions --- macrovision.js | 1024 ++++++++++++++++++++++++------------------------ 1 file changed, 518 insertions(+), 506 deletions(-) diff --git a/macrovision.js b/macrovision.js index 1c801954..1f1e6cd5 100644 --- a/macrovision.js +++ b/macrovision.js @@ -620,8 +620,8 @@ function snapPos(coords) { !config.groundSnap || altHeld ? coords.y : Math.abs(coords.y) < config.height.toNumber("meters") / 20 - ? 0 - : coords.y, + ? 0 + : coords.y, }; } @@ -674,10 +674,10 @@ function updateEntityElement(entity, element) { element.style.setProperty( "--entity-height", "'" + - entity.views[view].height - .to(config.height.units[0].unit.name) - .format({ precision: 2 }) + - "'" + entity.views[view].height + .to(config.height.units[0].unit.name) + .format({ precision: 2 }) + + "'" ); const pixels = math.divide(entity.views[view].height, config.height) * @@ -987,7 +987,7 @@ function updateEntityProperties(element) { element.style.setProperty( "--rotation", (entity.rotation * 180) / Math.PI + - "deg" + "deg" ); element.style.setProperty("--brightness", entity.brightness); } @@ -1651,11 +1651,11 @@ function defineAttributeGetters(view) { if (val.defaultUnit !== undefined) { view.units[key] = val.defaultUnit; } - + if (view[key] !== undefined) { return; } - + Object.defineProperty(view, key, { get: function () { return math.multiply( @@ -1764,12 +1764,12 @@ function makeEntity(info, views, sizes, forms = {}) { type: "energy", base: math.unit( 2000 * - Math.pow( - view.attributes.weight.base.toNumber( - "lbs" - ) / 150, - 3 / 4 - ), + Math.pow( + view.attributes.weight.base.toNumber( + "lbs" + ) / 150, + 3 / 4 + ), "kcal" ), }; @@ -1805,7 +1805,7 @@ function makeEntity(info, views, sizes, forms = {}) { ? 1 : 0.05) * view.attributes.weight.base.toNumber("lbs")) / - 150, + 150, "people" ), }; @@ -1816,7 +1816,7 @@ function makeEntity(info, views, sizes, forms = {}) { view.attributes.swallowSize === undefined ) { let size; - switch(config.autoSwallowSize) { + switch (config.autoSwallowSize) { case "casual": size = math.unit(20, "mL"); break; case "big-swallow": size = math.unit(50, "mL"); break; case "same-size-predator": size = math.unit(1, "people"); break; @@ -1913,7 +1913,7 @@ function makeEntity(info, views, sizes, forms = {}) { this.formSizes[form] = size; }); } else { - this.formSizes[size.form] = size; + this.formSizes[size.form] = size; } } }); @@ -2369,8 +2369,8 @@ function configViewOptions(entity, view) { const power = unitPowers[unitType]; - const baseValue = math.multiply(unit, math.pow(1/entity.scale, power)); - + const baseValue = math.multiply(unit, math.pow(1 / entity.scale, power)); + entity.views[view].attributes[key] = { name: name.value, power: power, @@ -2405,7 +2405,7 @@ function configViewOptions(entity, view) { } configViewOptions(entity, view); }); - + holder.appendChild(editButton); } @@ -2417,7 +2417,7 @@ function configViewOptions(entity, view) { delete entity.currentView.attributes[key]; configViewOptions(entity, view); }); - + holder.appendChild(deleteButton); } @@ -2459,9 +2459,9 @@ function configViewOptions(entity, view) { if (typeof value !== "number") { toast( "Invalid input: " + - value.format() + - " can't convert to " + - select.value + value.format() + + " can't convert to " + + select.value ); value = undefined; } @@ -3105,18 +3105,16 @@ function toggleFullScreen() { } } -function handleResize() { - const oldCanvasWidth = canvasWidth; +function handleResize(update = true) { entityX = document.querySelector("#entities").getBoundingClientRect().x; canvasWidth = document.querySelector("#display").clientWidth - 100; canvasHeight = document.querySelector("#display").clientHeight - 50; - const change = oldCanvasWidth / canvasWidth; - - updateSizes(); + if (update) + updateSizes(); } -function prepareSidebar() { +function preparePopoutMenu() { const menubar = document.querySelector("#sidebar-menu"); [ @@ -3251,6 +3249,121 @@ function prepareSidebar() { menubar.appendChild(buttonHolder); }); + + document + .querySelector("#menu-toggle-sidebar") + .addEventListener("click", (e) => { + const sidebar = document.querySelector("#options"); + if (sidebar.classList.contains("hidden")) { + sidebar.classList.remove("hidden"); + e.target.classList.remove("rotate-forward"); + e.target.classList.add("rotate-backward"); + } else { + sidebar.classList.add("hidden"); + e.target.classList.add("rotate-forward"); + e.target.classList.remove("rotate-backward"); + } + handleResize(); + }); + + document + .querySelector("#menu-fullscreen") + .addEventListener("click", toggleFullScreen); + + const sceneChoices = document.querySelector("#menu-preset ~ select"); + + Object.entries(scenes).forEach(([id, scene]) => { + const option = document.createElement("option"); + option.innerText = id; + option.value = id; + sceneChoices.appendChild(option); + }); + + document.querySelector("#menu-preset").addEventListener("click", (e) => { + const chosen = sceneChoices.value; + removeAllEntities(); + scenes[chosen](); + }); + + document.querySelector("#menu-clear").addEventListener("click", (e) => { + removeAllEntities(); + }); + + document.querySelector("#delete-entity").disabled = true; + document.querySelector("#delete-entity").addEventListener("click", (e) => { + if (selected) { + removeEntity(selected); + selected = null; + } + }); + + document + .querySelector("#menu-order-height") + .addEventListener("click", (e) => { + const order = Object.keys(entities).sort((a, b) => { + const entA = entities[a]; + const entB = entities[b]; + const viewA = entA.view; + const viewB = entB.view; + const heightA = entA.views[viewA].height.to("meter").value; + const heightB = entB.views[viewB].height.to("meter").value; + return heightA - heightB; + }); + + arrangeEntities(order); + }); + + + document + .querySelector("#options-world-fit") + .addEventListener("click", () => fitWorld(true)); + + document + .querySelector("#options-reset-pos-x") + .addEventListener("click", () => { + config.x = 0; + updateSizes(); + }); + document + .querySelector("#options-reset-pos-y") + .addEventListener("click", () => { + config.y = 0; + updateSizes(); + }); + + document.querySelector("#menu-permalink").addEventListener("click", (e) => { + linkScene(); + }); + + document.querySelector("#menu-export").addEventListener("click", (e) => { + copyScene(); + }); + + document.querySelector("#menu-import").addEventListener("click", (e) => { + pasteScene(); + }); + + document.querySelector("#menu-save").addEventListener("click", (e) => { + const name = document.querySelector("#menu-save ~ input").value; + if (/\S/.test(name)) { + saveScene(name); + } + updateSaveInfo(); + }); + + document.querySelector("#menu-load").addEventListener("click", (e) => { + const name = document.querySelector("#menu-load ~ select").value; + if (/\S/.test(name)) { + loadScene(name); + } + }); + + document.querySelector("#menu-delete").addEventListener("click", (e) => { + const name = document.querySelector("#menu-delete ~ select").value; + if (/\S/.test(name)) { + deleteScene(name); + } + }); } function checkBodyClass(cls) { @@ -3825,11 +3938,6 @@ function prepareSettings(userSettings) { }); } -function prepareMenu() { - prepareSidebar(); - updateSaveInfo(); -} - function updateSaveInfo() { const saves = getSaves(); const load = document.querySelector("#menu-load ~ select"); @@ -3976,10 +4084,7 @@ function entityRelativePosition(pos, entityElement) { return pos; } -document.addEventListener("DOMContentLoaded", () => { - prepareMenu(); - prepareEntities(); - +function setupMenuButtons() { document .querySelector("#copy-screenshot") .addEventListener("click", (e) => { @@ -4156,12 +4261,9 @@ document.addEventListener("DOMContentLoaded", () => { document.addEventListener("touchstart", (e) => { document.querySelector("#info-menu").classList.remove("visible"); }); +} - window.addEventListener("unload", () => { - saveScene("autosave"); - setUserSettings(exportUserSettings()); - }); - +function setupSidebar() { document .querySelector("#options-selected-entity") .addEventListener("input", (e) => { @@ -4172,25 +4274,6 @@ document.addEventListener("DOMContentLoaded", () => { } }); - document - .querySelector("#menu-toggle-sidebar") - .addEventListener("click", (e) => { - const sidebar = document.querySelector("#options"); - if (sidebar.classList.contains("hidden")) { - sidebar.classList.remove("hidden"); - e.target.classList.remove("rotate-forward"); - e.target.classList.add("rotate-backward"); - } else { - sidebar.classList.add("hidden"); - e.target.classList.add("rotate-forward"); - e.target.classList.remove("rotate-backward"); - } - handleResize(); - }); - - document - .querySelector("#menu-fullscreen") - .addEventListener("click", toggleFullScreen); document .querySelector("#options-order-forward") @@ -4266,263 +4349,62 @@ document.addEventListener("DOMContentLoaded", () => { updateSizes(); }); - const sceneChoices = document.querySelector("#menu-preset ~ select"); + const formList = document.querySelector("#entity-form"); - Object.entries(scenes).forEach(([id, scene]) => { - const option = document.createElement("option"); - option.innerText = id; - option.value = id; - sceneChoices.appendChild(option); - }); + formList.addEventListener("input", (e) => { + const entity = entities[selected.dataset.key]; + entity.form = e.target.value; - document.querySelector("#menu-preset").addEventListener("click", (e) => { - const chosen = sceneChoices.value; - removeAllEntities(); - scenes[chosen](); - }); + const oldView = entity.currentView; - entityX = document.querySelector("#entities").getBoundingClientRect().x; - canvasWidth = document.querySelector("#display").clientWidth - 100; - canvasHeight = document.querySelector("#display").clientHeight - 50; + entity.view = entity.formViews[entity.form]; - document - .querySelector("#options-height-value") - .addEventListener("change", (e) => { - updateWorldHeight(); - }); + // to set the size properly, even if we use a non-default view + if (Object.keys(entity.forms).length > 0) + entity.views[entity.view].height = + entity.formSizes[entity.form].height; - document - .querySelector("#options-height-value") - .addEventListener("keydown", (e) => { - e.stopPropagation(); + let found = Object.entries(entity.views).find(([key, view]) => { + return view.form === entity.form && view.name === oldView.name; }); - const unitSelector = document.querySelector("#options-height-unit"); + const newView = found ? found[0] : entity.formViews[entity.form]; - Object.entries(unitChoices.length).forEach(([group, entries]) => { - const optGroup = document.createElement("optgroup"); - optGroup.label = group; - unitSelector.appendChild(optGroup); + entity.view = newView; + preloadViews(entity); - entries.forEach((entry) => { - const option = document.createElement("option"); - option.innerText = entry; + configViewList(entity, entity.view); - // we haven't loaded user settings yet, so we can't choose the unit just yet + const image = entity.views[entity.view].image; + selected.querySelector(".entity-image").src = image.source; - unitSelector.appendChild(option); - }); - }); + configViewOptions(entity, entity.view); - unitSelector.addEventListener("input", selectNewUnit); + displayAttribution(image.source); - param = window.location.hash; + if (image.bottom !== undefined) { + selected + .querySelector(".entity-image") + .style.setProperty("--offset", (-1 + image.bottom) * 100 + "%"); + } else { + selected + .querySelector(".entity-image") + .style.setProperty("--offset", -1 * 100 + "%"); + } - // we now use the fragment for links, but we should still support old stuff: + if (config.autoFitSize) { + let targets = {}; + targets[selected.dataset.key] = entities[selected.dataset.key]; + fitEntities(targets); + } - if (param.length > 0) { - param = param.substring(1); - } else { - param = new URL(window.location.href).searchParams.get("scene"); - } + configSizeList(entity); + updateSizes(); + updateEntityOptions(entities[selected.dataset.key], e.target.value); + updateViewOptions(entities[selected.dataset.key], entity.view); + }); - document.querySelector("#world").addEventListener("mousedown", (e) => { - // only middle mouse clicks - if (e.which == 2) { - panning = true; - panOffsetX = e.clientX; - panOffsetY = e.clientY; - - Object.keys(entities).forEach((key) => { - document - .querySelector("#entity-" + key) - .classList.add("no-transition"); - }); - } - }); - - document.addEventListener("mouseup", (e) => { - if (e.which == 2) { - panning = false; - Object.keys(entities).forEach((key) => { - document - .querySelector("#entity-" + key) - .classList.remove("no-transition"); - }); - } - }); - - document.querySelector("#world").addEventListener("touchstart", (e) => { - if (!rulerMode) { - panning = true; - panOffsetX = e.touches[0].clientX; - panOffsetY = e.touches[0].clientY; - e.preventDefault(); - Object.keys(entities).forEach((key) => { - document - .querySelector("#entity-" + key) - .classList.add("no-transition"); - }); - } - }); - - document.querySelector("#world").addEventListener("touchend", (e) => { - panning = false; - Object.keys(entities).forEach((key) => { - document - .querySelector("#entity-" + key) - .classList.remove("no-transition"); - }); - }); - document.querySelector("#world").addEventListener("mousedown", (e) => { - // only left mouse clicks - if (e.which == 1 && rulerMode) { - let entX = document - .querySelector("#entities") - .getBoundingClientRect().x; - let entY = document - .querySelector("#entities") - .getBoundingClientRect().y; - let pos = pix2pos({ x: e.clientX - entX, y: e.clientY - entY }); - - if (config.rulersStick && selected) { - pos = entityRelativePosition(pos, selected); - } - currentRuler = { - x0: pos.x, - y0: pos.y, - x1: pos.y, - y1: pos.y, - entityKey: null, - }; - - if (config.rulersStick && selected) { - currentRuler.entityKey = selected.dataset.key; - } - } - }); - document.querySelector("#world").addEventListener("mouseup", (e) => { - // only left mouse clicks - if (e.which == 1 && currentRuler) { - rulers.push(currentRuler); - currentRuler = null; - rulerMode = false; - } - }); - - document.querySelector("#world").addEventListener("touchstart", (e) => { - if (rulerMode) { - let entX = document - .querySelector("#entities") - .getBoundingClientRect().x; - let entY = document - .querySelector("#entities") - .getBoundingClientRect().y; - let pos = pix2pos({ - x: e.touches[0].clientX - entX, - y: e.touches[0].clientY - entY, - }); - - if (config.rulersStick && selected) { - pos = entityRelativePosition(pos, selected); - } - currentRuler = { - x0: pos.x, - y0: pos.y, - x1: pos.y, - y1: pos.y, - entityKey: null, - }; - if (config.rulersStick && selected) { - currentRuler.entityKey = selected.dataset.key; - } - } - }); - document.querySelector("#world").addEventListener("touchend", (e) => { - if (currentRuler) { - rulers.push(currentRuler); - currentRuler = null; - rulerMode = false; - } - }); - - document.querySelector("body").appendChild(testCtx.canvas); - - world.addEventListener("mousedown", (e) => deselect(e)); - world.addEventListener("touchstart", (e) => - deselect({ - which: 1, - }) - ); - document.querySelector("#entities").addEventListener("mousedown", deselect); - document.querySelector("#display").addEventListener("mousedown", deselect); - document.addEventListener("mouseup", (e) => clickUp(e)); - document.addEventListener("touchend", (e) => { - const fakeEvent = { - target: e.target, - clientX: e.changedTouches[0].clientX, - clientY: e.changedTouches[0].clientY, - which: 1, - }; - clickUp(fakeEvent); - }); - - const formList = document.querySelector("#entity-form"); - - formList.addEventListener("input", (e) => { - const entity = entities[selected.dataset.key]; - entity.form = e.target.value; - - const oldView = entity.currentView; - - entity.view = entity.formViews[entity.form]; - - // to set the size properly, even if we use a non-default view - if (Object.keys(entity.forms).length > 0) - entity.views[entity.view].height = - entity.formSizes[entity.form].height; - - let found = Object.entries(entity.views).find(([key, view]) => { - return view.form === entity.form && view.name === oldView.name; - }); - - const newView = found ? found[0] : entity.formViews[entity.form]; - - entity.view = newView; - preloadViews(entity); - - configViewList(entity, entity.view); - - const image = entity.views[entity.view].image; - selected.querySelector(".entity-image").src = image.source; - - configViewOptions(entity, entity.view); - - displayAttribution(image.source); - - if (image.bottom !== undefined) { - selected - .querySelector(".entity-image") - .style.setProperty("--offset", (-1 + image.bottom) * 100 + "%"); - } else { - selected - .querySelector(".entity-image") - .style.setProperty("--offset", -1 * 100 + "%"); - } - - if (config.autoFitSize) { - let targets = {}; - targets[selected.dataset.key] = entities[selected.dataset.key]; - fitEntities(targets); - } - - configSizeList(entity); - updateSizes(); - updateEntityOptions(entities[selected.dataset.key], e.target.value); - updateViewOptions(entities[selected.dataset.key], entity.view); - }); - - const viewList = document.querySelector("#entity-view"); + const viewList = document.querySelector("#entity-view"); document.querySelector("#entity-view").addEventListener("input", (e) => { const entity = entities[selected.dataset.key]; @@ -4560,36 +4442,9 @@ document.addEventListener("DOMContentLoaded", () => { viewList.classList.remove("nsfw"); } }); +} - clearViewList(); - - document.querySelector("#menu-clear").addEventListener("click", (e) => { - removeAllEntities(); - }); - - document.querySelector("#delete-entity").disabled = true; - document.querySelector("#delete-entity").addEventListener("click", (e) => { - if (selected) { - removeEntity(selected); - selected = null; - } - }); - - document - .querySelector("#menu-order-height") - .addEventListener("click", (e) => { - const order = Object.keys(entities).sort((a, b) => { - const entA = entities[a]; - const entB = entities[b]; - const viewA = entA.view; - const viewB = entB.view; - const heightA = entA.views[viewA].height.to("meter").value; - const heightB = entB.views[viewB].height.to("meter").value; - return heightA - heightB; - }); - - arrangeEntities(order); - }); +function setupScrollButtons() { // TODO: write some generic logic for this lol @@ -4795,23 +4650,164 @@ document.addEventListener("DOMContentLoaded", () => { document.querySelector("#fit").addEventListener("touchstart", (e) => { e.stopPropagation(); }); +} - document - .querySelector("#options-world-fit") - .addEventListener("click", () => fitWorld(true)); +function prepareMenu() { + preparePopoutMenu(); + updateSaveInfo(); + setupMenuButtons(); + setupSidebar(); + setupScrollButtons(); +} - document - .querySelector("#options-reset-pos-x") - .addEventListener("click", () => { - config.x = 0; - updateSizes(); - }); - document - .querySelector("#options-reset-pos-y") - .addEventListener("click", () => { - config.y = 0; - updateSizes(); +function prepareEvents() { + window.addEventListener("unload", () => { + saveScene("autosave"); + setUserSettings(exportUserSettings()); + }); + + + + document.querySelector("#world").addEventListener("mousedown", (e) => { + // only middle mouse clicks + if (e.which == 2) { + panning = true; + panOffsetX = e.clientX; + panOffsetY = e.clientY; + + Object.keys(entities).forEach((key) => { + document + .querySelector("#entity-" + key) + .classList.add("no-transition"); + }); + } + }); + + document.addEventListener("mouseup", (e) => { + if (e.which == 2) { + panning = false; + Object.keys(entities).forEach((key) => { + document + .querySelector("#entity-" + key) + .classList.remove("no-transition"); + }); + } + }); + + document.querySelector("#world").addEventListener("touchstart", (e) => { + if (!rulerMode) { + panning = true; + panOffsetX = e.touches[0].clientX; + panOffsetY = e.touches[0].clientY; + e.preventDefault(); + Object.keys(entities).forEach((key) => { + document + .querySelector("#entity-" + key) + .classList.add("no-transition"); + }); + } + }); + + document.querySelector("#world").addEventListener("touchend", (e) => { + panning = false; + Object.keys(entities).forEach((key) => { + document + .querySelector("#entity-" + key) + .classList.remove("no-transition"); }); + }); + document.querySelector("#world").addEventListener("mousedown", (e) => { + // only left mouse clicks + if (e.which == 1 && rulerMode) { + let entX = document + .querySelector("#entities") + .getBoundingClientRect().x; + let entY = document + .querySelector("#entities") + .getBoundingClientRect().y; + let pos = pix2pos({ x: e.clientX - entX, y: e.clientY - entY }); + + if (config.rulersStick && selected) { + pos = entityRelativePosition(pos, selected); + } + currentRuler = { + x0: pos.x, + y0: pos.y, + x1: pos.y, + y1: pos.y, + entityKey: null, + }; + + if (config.rulersStick && selected) { + currentRuler.entityKey = selected.dataset.key; + } + } + }); + document.querySelector("#world").addEventListener("mouseup", (e) => { + // only left mouse clicks + if (e.which == 1 && currentRuler) { + rulers.push(currentRuler); + currentRuler = null; + rulerMode = false; + } + }); + + document.querySelector("#world").addEventListener("touchstart", (e) => { + if (rulerMode) { + let entX = document + .querySelector("#entities") + .getBoundingClientRect().x; + let entY = document + .querySelector("#entities") + .getBoundingClientRect().y; + let pos = pix2pos({ + x: e.touches[0].clientX - entX, + y: e.touches[0].clientY - entY, + }); + + if (config.rulersStick && selected) { + pos = entityRelativePosition(pos, selected); + } + currentRuler = { + x0: pos.x, + y0: pos.y, + x1: pos.y, + y1: pos.y, + entityKey: null, + }; + if (config.rulersStick && selected) { + currentRuler.entityKey = selected.dataset.key; + } + } + }); + document.querySelector("#world").addEventListener("touchend", (e) => { + if (currentRuler) { + rulers.push(currentRuler); + currentRuler = null; + rulerMode = false; + } + }); + + document.querySelector("body").appendChild(testCtx.canvas); + + world.addEventListener("mousedown", (e) => deselect(e)); + world.addEventListener("touchstart", (e) => + deselect({ + which: 1, + }) + ); + document.querySelector("#entities").addEventListener("mousedown", deselect); + document.querySelector("#display").addEventListener("mousedown", deselect); + document.addEventListener("mouseup", (e) => clickUp(e)); + document.addEventListener("touchend", (e) => { + const fakeEvent = { + target: e.target, + clientX: e.changedTouches[0].clientX, + clientY: e.changedTouches[0].clientY, + which: 1, + }; + clickUp(fakeEvent); + }); document.addEventListener("keydown", (e) => { if (e.key == "Delete" || e.key == "Backspace") { @@ -4843,78 +4839,6 @@ document.addEventListener("DOMContentLoaded", () => { } }); - window.addEventListener("resize", handleResize); - - // TODO: further investigate why the tool initially starts out with wrong - // values under certain circumstances (seems to be narrow aspect ratios - - // maybe the menu bar is animating when it shouldn't) - - setTimeout(handleResize, 250); - setTimeout(handleResize, 500); - setTimeout(handleResize, 750); - setTimeout(handleResize, 1000); - - document.querySelector("#menu-permalink").addEventListener("click", (e) => { - linkScene(); - }); - - document.querySelector("#menu-export").addEventListener("click", (e) => { - copyScene(); - }); - - document.querySelector("#menu-import").addEventListener("click", (e) => { - pasteScene(); - }); - - document.querySelector("#menu-save").addEventListener("click", (e) => { - const name = document.querySelector("#menu-save ~ input").value; - if (/\S/.test(name)) { - saveScene(name); - } - updateSaveInfo(); - }); - - document.querySelector("#menu-load").addEventListener("click", (e) => { - const name = document.querySelector("#menu-load ~ select").value; - if (/\S/.test(name)) { - loadScene(name); - } - }); - - document.querySelector("#menu-delete").addEventListener("click", (e) => { - const name = document.querySelector("#menu-delete ~ select").value; - if (/\S/.test(name)) { - deleteScene(name); - } - }); - - document - .querySelector("#menu-load-autosave") - .addEventListener("click", (e) => { - loadScene("autosave"); - }); - - document.querySelector("#menu-add-image").addEventListener("click", (e) => { - document.querySelector("#file-upload-picker").click(); - }); - - document - .querySelector("#file-upload-picker") - .addEventListener("change", (e) => { - if (e.target.files.length > 0) { - for (let i = 0; i < e.target.files.length; i++) { - customEntityFromFile(e.target.files[i]); - } - } - }); - - document - .querySelector("#menu-clear-rulers") - .addEventListener("click", (e) => { - rulers = []; - drawRulers(); - }); - document.addEventListener("paste", (e) => { let index = 0; let item = null; @@ -4956,47 +4880,6 @@ document.addEventListener("DOMContentLoaded", () => { customEntityFromFile(e.dataTransfer.files[0], coords.x, coords.y); } }); - clearEntityOptions(); - clearViewOptions(); - clearAttribution(); - - // we do this last because configuring settings can cause things - // to happen (e.g. auto-fit) - prepareSettings(getUserSettings()); - - // now that we have this loaded, we can set it - - unitSelector.dataset.oldUnit = defaultUnits.length[config.units]; - - document.querySelector("#options-height-unit").value = - defaultUnits.length[config.units]; - - // ...and then update the world height by setting off an input event - - document - .querySelector("#options-height-unit") - .dispatchEvent(new Event("input", {})); - - if (param === null) { - scenes["Empty"](); - } else { - try { - const data = JSON.parse(b64DecodeUnicode(param), math.reviver); - if (data.entities === undefined) { - return; - } - if (data.world === undefined) { - return; - } - - importScene(data); - } catch (err) { - console.error(err); - scenes["Empty"](); - - // probably wasn't valid data - } - } document.querySelector("#world").addEventListener("wheel", (e) => { let magnitude = Math.abs(e.deltaY / 100); @@ -5196,16 +5079,146 @@ document.addEventListener("DOMContentLoaded", () => { { passive: false } ); - updateWorldHeight(); - document .querySelector("#search-box") .addEventListener("change", (e) => doSearch(e.target.value)); - document .querySelector("#search-box") .addEventListener("keydown", e => e.stopPropagation()); +} + +document.addEventListener("DOMContentLoaded", () => { + + prepareMenu(); + prepareEntities(); + prepareEvents(); + + handleResize(false); + + document + .querySelector("#options-height-value") + .addEventListener("change", (e) => { + updateWorldHeight(); + }); + + document + .querySelector("#options-height-value") + .addEventListener("keydown", (e) => { + e.stopPropagation(); + }); + + const unitSelector = document.querySelector("#options-height-unit"); + + Object.entries(unitChoices.length).forEach(([group, entries]) => { + const optGroup = document.createElement("optgroup"); + optGroup.label = group; + unitSelector.appendChild(optGroup); + + entries.forEach((entry) => { + const option = document.createElement("option"); + option.innerText = entry; + + // we haven't loaded user settings yet, so we can't choose the unit just yet + + unitSelector.appendChild(option); + }); + }); + + unitSelector.addEventListener("input", selectNewUnit); + + param = window.location.hash; + + // we now use the fragment for links, but we should still support old stuff: + + if (param.length > 0) { + param = param.substring(1); + } else { + param = new URL(window.location.href).searchParams.get("scene"); + } + + clearViewList(); + + window.addEventListener("resize", handleResize); + + // TODO: further investigate why the tool initially starts out with wrong + // values under certain circumstances (seems to be narrow aspect ratios - + // maybe the menu bar is animating when it shouldn't) + + setTimeout(handleResize, 250); + setTimeout(handleResize, 500); + setTimeout(handleResize, 750); + setTimeout(handleResize, 1000); + + document + .querySelector("#menu-load-autosave") + .addEventListener("click", (e) => { + loadScene("autosave"); + }); + + document.querySelector("#menu-add-image").addEventListener("click", (e) => { + document.querySelector("#file-upload-picker").click(); + }); + + document + .querySelector("#file-upload-picker") + .addEventListener("change", (e) => { + if (e.target.files.length > 0) { + for (let i = 0; i < e.target.files.length; i++) { + customEntityFromFile(e.target.files[i]); + } + } + }); + + document + .querySelector("#menu-clear-rulers") + .addEventListener("click", (e) => { + rulers = []; + drawRulers(); + }); + clearEntityOptions(); + clearViewOptions(); + clearAttribution(); + + // we do this last because configuring settings can cause things + // to happen (e.g. auto-fit) + prepareSettings(getUserSettings()); + + // now that we have this loaded, we can set it + + unitSelector.dataset.oldUnit = defaultUnits.length[config.units]; + + document.querySelector("#options-height-unit").value = + defaultUnits.length[config.units]; + + // ...and then update the world height by setting off an input event + + document + .querySelector("#options-height-unit") + .dispatchEvent(new Event("input", {})); + + if (param === null) { + scenes["Empty"](); + } else { + try { + const data = JSON.parse(b64DecodeUnicode(param), math.reviver); + if (data.entities === undefined) { + return; + } + if (data.world === undefined) { + return; + } + + importScene(data); + } catch (err) { + console.error(err); + scenes["Empty"](); + + // probably wasn't valid data + } + } + + updateWorldHeight(); // Webkit doesn't draw resized SVGs correctly. It will always draw them at their intrinsic size, I think // This checks for that. webkitBugTest.onload = () => { @@ -5317,20 +5330,20 @@ const filterDefs = { extract: (maker) => maker.sizes && maker.sizes.length > 0 ? Array.from( - maker.sizes.reduce((result, size) => { - if (result && !size.default) { - return result; - } - let meters = size.height.toNumber("meters"); - if (meters < 1e-1) { - return ["micro"]; - } else if (meters < 1e1) { - return ["moderate"]; - } else { - return ["macro"]; - } - }, null) - ) + maker.sizes.reduce((result, size) => { + if (result && !size.default) { + return result; + } + let meters = size.height.toNumber("meters"); + if (meters < 1e-1) { + return ["micro"]; + } else if (meters < 1e1) { + return ["moderate"]; + } else { + return ["macro"]; + } + }, null) + ) : [], render: (tag) => { return { @@ -5355,27 +5368,27 @@ const filterDefs = { extract: (maker) => maker.sizes ? Array.from( - maker.sizes.reduce((set, size) => { - const height = size.height; - - let result = Object.entries(sizeCategories).reduce( - (result, [name, value]) => { - if (result) { - return result; - } else { - if (math.compare(height, value) <= 0) { - return name; - } - } - }, - null - ); - - set.add(result ? result : "infinite"); - - return set; - }, new Set()) - ) + maker.sizes.reduce((set, size) => { + const height = size.height; + + let result = Object.entries(sizeCategories).reduce( + (result, [name, value]) => { + if (result) { + return result; + } else { + if (math.compare(height, value) <= 0) { + return name; + } + } + }, + null + ); + + set.add(result ? result : "infinite"); + + return set; + }, new Set()) + ) : [], render: (tag) => tag[0].toUpperCase() + tag.slice(1), sort: (tag1, tag2) => { @@ -5667,8 +5680,8 @@ function spawnAll() { entity, entity.view, -worldWidth * 0.45 + - config.x + - (worldWidth * 0.9 * index) / (count - 1), + config.x + + (worldWidth * 0.9 * index) / (count - 1), config.y ); index += 1; @@ -5774,7 +5787,6 @@ function updateFilter() { keep = false; } }) - if ( searchText != "" && @@ -5801,7 +5813,7 @@ function updateFilter() { }); const button = document.querySelector("#spawn-all") - + button.innerText = "Spawn " + count + " filtered " + (count == 1 ? "entity" : "entities") + "."; if (replace) { @@ -5923,9 +5935,9 @@ function updateWorldHeight() { } catch { toast( "Invalid input: " + - rawValue + - " can't be converted to " + - unit + rawValue + + " can't be converted to " + + unit ); } }