-
-
- Submit Your Character
-
- Submit Your Character
- World Info
diff --git a/macrovision.js b/macrovision.js
index 1b8a9a53..1cc7d55b 100644
--- a/macrovision.js
+++ b/macrovision.js
@@ -1452,7 +1452,7 @@ function drawHorizontalScale(ifDirty = false) {
// calling the constructor -- e.g. making a list of authors and
// owners. So, this function is used to generate that information.
// It is invoked like makeEntity so that it can be dropped in easily,
-// but returns an object that lets you construct many copies of an entity,
+// but returns an object that lets you construct many copies of an entity,
// rather than creating a new entity.
function createEntityMaker(info, views, sizes, forms) {
const maker = {};
@@ -3679,15 +3679,6 @@ document.addEventListener("DOMContentLoaded", () => {
prepareMenu();
prepareEntities();
- document.querySelector("#open-help").addEventListener("click", (e) => {
- setHelpDate();
- document.querySelector("#open-help").classList.remove("highlighted");
- window.open(
- "https://www.notion.so/Macrovision-5c7f9377424743358ddf6db5671f439e",
- "_blank"
- );
- });
-
document
.querySelector("#copy-screenshot")
.addEventListener("click", (e) => {
@@ -3734,10 +3725,18 @@ document.addEventListener("DOMContentLoaded", () => {
e.stopPropagation();
});
+ document.querySelector("#sidebar-menu").addEventListener("touchstart", (e) => {
+ e.stopPropagation();
+ });
+
document.addEventListener("click", (e) => {
document.querySelector("#sidebar-menu").classList.remove("visible");
});
+ document.addEventListener("touchstart", (e) => {
+ document.querySelector("#sidebar-menu").classList.remove("visible");
+ });
+
document
.querySelector("#toggle-settings")
.addEventListener("click", (e) => {
@@ -3767,10 +3766,96 @@ document.addEventListener("DOMContentLoaded", () => {
e.stopPropagation();
});
+ document.querySelector("#settings-menu").addEventListener("touchstart", (e) => {
+ e.stopPropagation();
+ });
+
document.addEventListener("click", (e) => {
document.querySelector("#settings-menu").classList.remove("visible");
});
+ document.addEventListener("touchstart", (e) => {
+ document.querySelector("#settings-menu").classList.remove("visible");
+ });
+
+ document.querySelector("#toggle-filters").addEventListener("click", (e) => {
+ const popoutMenu = document.querySelector("#filters-menu");
+ if (popoutMenu.classList.contains("visible")) {
+ popoutMenu.classList.remove("visible");
+ } else {
+ document
+ .querySelectorAll(".popout-menu")
+ .forEach((menu) => menu.classList.remove("visible"));
+ const rect = e.target.getBoundingClientRect();
+ popoutMenu.classList.add("visible");
+ popoutMenu.style.left = rect.x + rect.width + 10 + "px";
+ popoutMenu.style.top = rect.y + rect.height + 10 + "px";
+
+ let menuWidth = popoutMenu.getBoundingClientRect().width;
+ let screenWidth = window.innerWidth;
+
+ if (menuWidth * 1.5 > screenWidth) {
+ popoutMenu.style.left = 25 + "px";
+ }
+ }
+ e.stopPropagation();
+ });
+
+ document.querySelector("#filters-menu").addEventListener("click", (e) => {
+ e.stopPropagation();
+ });
+
+ document.querySelector("#filters-menu").addEventListener("touchstart", (e) => {
+ e.stopPropagation();
+ });
+
+ document.addEventListener("click", (e) => {
+ document.querySelector("#filters-menu").classList.remove("visible");
+ });
+
+ document.addEventListener("touchstart", (e) => {
+ document.querySelector("#filters-menu").classList.remove("visible");
+ });
+
+ document.querySelector("#toggle-info").addEventListener("click", (e) => {
+ const popoutMenu = document.querySelector("#info-menu");
+ if (popoutMenu.classList.contains("visible")) {
+ popoutMenu.classList.remove("visible");
+ } else {
+ document
+ .querySelectorAll(".popout-menu")
+ .forEach((menu) => menu.classList.remove("visible"));
+ const rect = e.target.getBoundingClientRect();
+ popoutMenu.classList.add("visible");
+ popoutMenu.style.left = rect.x + rect.width + 10 + "px";
+ popoutMenu.style.top = rect.y + rect.height + 10 + "px";
+
+ let menuWidth = popoutMenu.getBoundingClientRect().width;
+ let screenWidth = window.innerWidth;
+
+ if (menuWidth * 1.5 > screenWidth) {
+ popoutMenu.style.left = 25 + "px";
+ }
+ }
+ e.stopPropagation();
+ });
+
+ document.querySelector("#info-menu").addEventListener("click", (e) => {
+ e.stopPropagation();
+ });
+
+ document.querySelector("#info-menu").addEventListener("touchstart", (e) => {
+ e.stopPropagation();
+ });
+
+ document.addEventListener("click", (e) => {
+ document.querySelector("#info-menu").classList.remove("visible");
+ });
+
+ document.addEventListener("touchstart", (e) => {
+ document.querySelector("#info-menu").classList.remove("visible");
+ });
+
window.addEventListener("unload", () => {
saveScene("autosave");
setUserSettings(exportUserSettings());
@@ -4845,6 +4930,8 @@ document.addEventListener("DOMContentLoaded", () => {
);
}
};
+
+ updateFilter();
});
let searchText = "";
@@ -4898,13 +4985,6 @@ function makeCustomEntity(url, x = 0.5, y = 0.5) {
}
const filterDefs = {
- none: {
- id: "none",
- name: "No Filter",
- extract: (maker) => [],
- render: (name) => name,
- sort: (tag1, tag2) => tag1[1].localeCompare(tag2[1]),
- },
author: {
id: "author",
name: "Authors",
@@ -5027,6 +5107,8 @@ const filterDefs = {
},
};
+const filterStates = {};
+
const sizeCategories = {
atomic: math.unit(100, "angstroms"),
microscopic: math.unit(100, "micrometers"),
@@ -5079,20 +5161,18 @@ function prepareEntities() {
return x.name.localeCompare(y.name);
});
const holder = document.querySelector("#spawners");
- const filterHolder = document.querySelector("#filters");
+ const filterMenu = document.querySelector("#filters-menu");
const categorySelect = document.createElement("select");
categorySelect.id = "category-picker";
- const filterSelect = document.createElement("select");
- filterSelect.id = "filter-picker";
holder.appendChild(categorySelect);
- filterHolder.appendChild(filterSelect);
const filterSets = {};
Object.values(filterDefs).forEach((filter) => {
filterSets[filter.id] = new Set();
+ filterStates[filter.id] = false;
});
Object.entries(availableEntities).forEach(([category, entityList]) => {
@@ -5183,76 +5263,36 @@ function prepareEntities() {
});
Object.values(filterDefs).forEach((filter) => {
- const option = document.createElement("option");
- option.innerText = filter.name;
- option.value = filter.id;
- filterSelect.appendChild(option);
+ const filterHolder = document.createElement("label");
+ filterHolder.setAttribute("for", "filter-toggle-" + filter.id);
+ filterHolder.classList.add("filter-holder");
+
+ const filterToggle = document.createElement("input");
+ filterToggle.type = "checkbox";
+ filterToggle.id = "filter-toggle-" + filter.id;
+ filterHolder.appendChild(filterToggle);
+
+ filterToggle.addEventListener("input", e => {
+ filterStates[filter.id] = filterToggle.checked
+ if (filterToggle.checked) {
+ filterHolder.classList.add("enabled");
+ } else {
+ filterHolder.classList.remove("enabled");
+ }
+ clearFilter();
+ updateFilter();
+ });
+
+ const filterLabel = document.createElement("div");
+ filterLabel.innerText = filter.name;
+ filterHolder.appendChild(filterLabel);
const filterNameSelect = document.createElement("select");
filterNameSelect.classList.add("filter-select");
filterNameSelect.id = "filter-" + filter.id;
filterHolder.appendChild(filterNameSelect);
- const button = document.createElement("button");
- button.classList.add("filter-button");
- button.id = "create-filtered-" + filter.id + "-button";
- filterHolder.appendChild(button);
-
- const counter = document.createElement("div");
- counter.classList.add("button-counter");
- counter.innerText = "10";
- button.appendChild(counter);
- const i = document.createElement("i");
- i.classList.add("fas");
- i.classList.add("fa-plus");
- button.appendChild(i);
-
- button.addEventListener("click", (e) => {
- const makers = Array.from(
- document.querySelector(".entity-select.category-visible")
- ).filter((element) => !element.classList.contains("filtered"));
- const count = makers.length + 2;
- let index = 1;
-
- if (makers.length > 50) {
- if (
- !confirm(
- "Really spawn " + makers.length + " things at once?"
- )
- ) {
- return;
- }
- }
-
- const worldWidth =
- (config.height.toNumber("meters") / canvasHeight) * canvasWidth;
-
- const spawned = makers.map((element) => {
- const category =
- document.querySelector("#category-picker").value;
- const maker = availableEntities[category][element.value];
- const entity = maker.constructor();
- displayEntity(
- entity,
- entity.view,
- -worldWidth * 0.45 +
- config.x +
- (worldWidth * 0.9 * index) / (count - 1),
- config.y
- );
- index += 1;
- return entityIndex - 1;
- });
- updateSizes(true);
-
- if (config.autoFitAdd) {
- let targets = {};
- spawned.forEach((key) => {
- targets[key] = entities[key];
- });
- fitEntities(targets);
- }
- });
+ filterMenu.appendChild(filterHolder);
Array.from(filterSets[filter.id])
.map((name) => [name, filter.render(name)])
@@ -5269,6 +5309,14 @@ function prepareEntities() {
});
});
+ const spawnButton = document.createElement("button");
+ spawnButton.id = "spawn-all"
+ spawnButton.addEventListener("click", e => {
+ spawnAll();
+ });
+
+ filterMenu.appendChild(spawnButton);
+
console.log(
"Loaded " + Object.keys(availableEntitiesByName).length + " entities"
);
@@ -5298,20 +5346,49 @@ function prepareEntities() {
recomputeFilters();
- filterSelect.addEventListener("input", (e) => {
- const oldSelect = document.querySelector(
- ".filter-select.category-visible"
- );
- if (oldSelect) oldSelect.classList.remove("category-visible");
+ ratioInfo = document.body.querySelector(".extra-info");
+}
- const newSelect = document.querySelector("#filter-" + e.target.value);
- if (newSelect && e.target.value != "none")
- newSelect.classList.add("category-visible");
+function spawnAll() {
+ const makers = Array.from(
+ document.querySelector(".entity-select.category-visible")
+ ).filter((element) => !element.classList.contains("filtered"));
+ const count = makers.length + 2;
+ let index = 1;
- updateFilter();
+ if (makers.length > 50) {
+ if (!confirm("Really spawn " + makers.length + " things at once?")) {
+ return;
+ }
+ }
+
+ const worldWidth =
+ (config.height.toNumber("meters") / canvasHeight) * canvasWidth;
+
+ const spawned = makers.map((element) => {
+ const category = document.querySelector("#category-picker").value;
+ const maker = availableEntities[category][element.value];
+ const entity = maker.constructor();
+ displayEntity(
+ entity,
+ entity.view,
+ -worldWidth * 0.45 +
+ config.x +
+ (worldWidth * 0.9 * index) / (count - 1),
+ config.y
+ );
+ index += 1;
+ return entityIndex - 1;
});
+ updateSizes(true);
- ratioInfo = document.body.querySelector(".extra-info");
+ if (config.autoFitAdd) {
+ let targets = {};
+ spawned.forEach((key) => {
+ targets[key] = entities[key];
+ });
+ fitEntities(targets);
+ }
}
// Only display authors and owners if they appear
@@ -5325,75 +5402,64 @@ function recomputeFilters() {
filterSets[filter.id] = new Set();
});
- document
- .querySelectorAll(".entity-select.category-visible > option")
- .forEach((element) => {
- const entity = availableEntities[category][element.value];
-
- Object.values(filterDefs).forEach((filter) => {
- filter.extract(entity).forEach((result) => {
- filterSets[filter.id].add(result);
- });
+ availableEntities[category].forEach((entity) => {
+ Object.values(filterDefs).forEach((filter) => {
+ filter.extract(entity).forEach((result) => {
+ filterSets[filter.id].add(result);
});
});
+ });
Object.values(filterDefs).forEach((filter) => {
+ filterStates[filter.id] = false;
+ document.querySelector("#filter-toggle-" + filter.id).checked = false
+ document.querySelector("#filter-toggle-" + filter.id).dispatchEvent(new Event("click"))
// always show the "none" option
let found = filter.id == "none";
+ const filterSelect = document.querySelector("#filter-" + filter.id);
+ const filterSelectHolder = filterSelect.parentElement;
+ filterSelect.querySelectorAll("option").forEach((element) => {
+ if (
+ filterSets[filter.id].has(element.value) ||
+ filter.id == "none"
+ ) {
+ element.classList.remove("filtered");
+ element.disabled = false;
+ found = true;
+ } else {
+ element.classList.add("filtered");
+ element.disabled = true;
+ }
+ });
- document
- .querySelectorAll("#filter-" + filter.id + " > option")
- .forEach((element) => {
- if (
- filterSets[filter.id].has(element.value) ||
- filter.id == "none"
- ) {
- element.classList.remove("filtered");
- element.disabled = false;
- found = true;
- } else {
- element.classList.add("filtered");
- element.disabled = true;
- }
- });
-
- const filterOption = document.querySelector(
- "#filter-picker > option[value='" + filter.id + "']"
- );
if (found) {
- filterOption.classList.remove("filtered");
- filterOption.disabled = false;
+ filterSelectHolder.style.display = "";
} else {
- filterOption.classList.add("filtered");
- filterOption.disabled = true;
+ filterSelectHolder.style.display = "none";
}
});
-
- document.querySelector("#filter-picker").value = "none";
- document.querySelector("#filter-picker").dispatchEvent(new Event("input"));
}
function updateFilter() {
const category = document.querySelector("#category-picker").value;
- const type = document.querySelector("#filter-picker").value;
- const filterKeySelect = document.querySelector(
- ".filter-select.category-visible"
- );
- clearFilter();
+ const types = Object.values(filterDefs).filter(def => filterStates[def.id]).map(def => def.id)
+
+ const keys = {
- const noFilter = !filterKeySelect;
+ }
+
+ types.forEach(type => {
+ const filterKeySelect = document.querySelector("#filter-" + type);
+ keys[type] = filterKeySelect.value;
+ })
+
+ clearFilter();
- let key;
let current = document.querySelector(
".entity-select.category-visible"
).value;
- if (!noFilter) {
- key = filterKeySelect.value;
- current;
- }
-
let replace = current == "";
let first = null;
@@ -5403,16 +5469,18 @@ function updateFilter() {
document
.querySelectorAll(".entity-select.category-visible > option")
.forEach((element) => {
- let keep = noFilter;
+ let keep = true
- if (
- !noFilter &&
- filterDefs[type]
- .extract(availableEntities[category][element.value])
- .indexOf(key) >= 0
- ) {
- keep = true;
- }
+ types.forEach(type => {
+ if (
+ !(filterDefs[type]
+ .extract(availableEntities[category][element.value])
+ .indexOf(keys[type]) >= 0)
+ ) {
+ keep = false;
+ }
+ })
+
if (
searchText != "" &&
@@ -5438,13 +5506,9 @@ function updateFilter() {
}
});
- const button = document.querySelector(
- ".filter-select.category-visible + button"
- );
-
- if (button) {
- button.querySelector(".button-counter").innerText = count;
- }
+ const button = document.querySelector("#spawn-all")
+
+ button.innerText = "Spawn " + count + " filtered " + (count == 1 ? "entity" : "entities") + ".";
if (replace) {
document.querySelector(".entity-select.category-visible").value = first;