diff --git a/global/globalScript.js b/global/globalScript.js index bca46cd..880a3e1 100644 --- a/global/globalScript.js +++ b/global/globalScript.js @@ -5,7 +5,8 @@ const PAGES = { TOYS: 2, LICENSE: 3, LOADING: 4, - LIBS: 5 + LIBS: 5, + CRAFTING: 6 } const CONSOLE_COLORS = { red: "color: #FF0000;", @@ -189,6 +190,7 @@ document.addEventListener("DOMContentLoaded", async function () { case (PAGES.LICENSE): loadingScreenStars(); await loadingScreenLicense(); break case (PAGES.TOYS): loadingScreenStars(); break case (PAGES.LIBS): loadingScreenStars(); break + case (PAGES.CRAFTING): loadingScreenCrafting(); break } if (navBarPresent) { diff --git a/global/globalStyle.css b/global/globalStyle.css index 4df0fe6..3a974fd 100644 --- a/global/globalStyle.css +++ b/global/globalStyle.css @@ -64,6 +64,9 @@ canvas { margin: calc(3px * var(--pxDensity)) calc(3px * var(--pxDensity)) 0% 0%; width: round(auto, var(--pxDensity)); /*height: calc(6px * var(--pxDensity));*/ + border: none; + color: #ffffff; + font-size: inherit; } .switch { position: relative; @@ -109,4 +112,41 @@ canvas { aspect-ratio: 1 / 1; image-rendering: pixelated; transform: translate(-50%, -50%); +} +button { + display: inline-block; + background-color: var(--navBarBtn_Inner); + box-shadow: calc(1px * var(--pxDensity)) 0px var(--navBarBtn_Border), + calc(-1px * var(--pxDensity)) 0px var(--navBarBtn_Border), + 0px calc(1px * var(--pxDensity)) var(--navBarBtn_Border), + 0px calc(-1px * var(--pxDensity)) var(--navBarBtn_Border); + + padding: calc(1px * var(--pxDensity)); + margin: calc(3px * var(--pxDensity)) calc(3px * var(--pxDensity)) 0% 0%; + width: round(auto, var(--pxDensity)); + /*height: calc(6px * var(--pxDensity));*/ + border: none; + color: #ffffff; + font-size: inherit; +} +button:hover { + filter: brightness(1.35) drop-shadow(0px calc(1px * var(--pxDensity)) rgba(0, 0, 0, 0.5)); + cursor: pointer; +} +button:active { + filter: brightness(0.75); + transform: translateY(calc(1px * var(--pxDensity))); +} +button:disabled, button[disabled] { + filter: brightness(0.75) drop-shadow(0px calc(1px * var(--pxDensity)) rgba(0, 0, 0, 0.5)); + cursor: not-allowed; +} +button:disabled:hover, button[disabled]:hover { + filter: brightness(0.75) drop-shadow(0px calc(1px * var(--pxDensity)) rgba(0, 0, 0, 0.5)); + cursor: not-allowed; +} +button:disabled:active, button[disabled]:active { + filter: brightness(0.75) drop-shadow(0px calc(1px * var(--pxDensity)) rgba(0, 0, 0, 0.5)); + cursor: not-allowed; + transform: none; } \ No newline at end of file diff --git a/global/navBar.css b/global/navBar.css index 66482ed..ebb9378 100644 --- a/global/navBar.css +++ b/global/navBar.css @@ -20,27 +20,9 @@ li { padding: 0%; border: none; filter: drop-shadow(0px calc(1px * var(--pxDensity)) rgba(0, 0, 0, 0.5)); -} -button:hover { - filter: brightness(1.35) drop-shadow(0px calc(1px * var(--pxDensity)) rgba(0, 0, 0, 0.5)); - cursor: pointer; -} -button:active { - filter: brightness(0.75); - transform: translateY(calc(1px * var(--pxDensity))); -} -.button:disabled, button[disabled] { - filter: brightness(0.75) drop-shadow(0px calc(1px * var(--pxDensity)) rgba(0, 0, 0, 0.5)); - cursor: not-allowed; -} -.button:disabled:hover, button[disabled]:hover { - filter: brightness(0.75) drop-shadow(0px calc(1px * var(--pxDensity)) rgba(0, 0, 0, 0.5)); - cursor: not-allowed; -} -.button:disabled:active, button[disabled]:active { - filter: brightness(0.75) drop-shadow(0px calc(1px * var(--pxDensity)) rgba(0, 0, 0, 0.5)); - cursor: not-allowed; - transform: none; + margin: 0%; + box-shadow: none; + width: auto; } .navBtnImg { width: calc(12px * var(--pxDensity)); diff --git a/index.html b/index.html index 8c67e49..d9ae5fb 100644 --- a/index.html +++ b/index.html @@ -35,7 +35,7 @@
- + @@ -48,7 +48,7 @@
- + diff --git a/toys/crafting/index.html b/toys/crafting/index.html new file mode 100644 index 0000000..81b0cc9 --- /dev/null +++ b/toys/crafting/index.html @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + Byte Dice - Crafting + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+
+ +
+
+ + + +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/toys/crafting/script.js b/toys/crafting/script.js new file mode 100644 index 0000000..bc4db57 --- /dev/null +++ b/toys/crafting/script.js @@ -0,0 +1,81 @@ +CURRENT_PAGE = PAGES.CRAFTING + +let tomlInputContainer = document.getElementById("tomlInputContainer") +let collapseButton = document.getElementById("collapseButton") +let treeStatic = document.getElementById("treeStaticContainer") +let treeScale = document.getElementById("treeScaleContainer") + + +let mouseX = 0 +let mouseY = 0 +let dragX = 0 +let dragY = 0 +let dragOffsetX = 0 +let dragOffsetY = 0 +let isDragging = false +let scale = 1 + + +let isCollapsed = false + + +document.addEventListener("mousemove", function(event) { + mouseX = event.clientX; + mouseY = event.clientY; +}) + + +function collapseInput() { + const COLLAPSE = "collapse 0.5s cubic-bezier(0, 0, 0, 1.46) forwards" + tomlInputContainer.style.animation = COLLAPSE + isCollapsed = true + collapseButton.textContent = ">" +} + + +function unCollapseInput() { + const UN_COLLAPSE = "un-collapse 0.5s cubic-bezier(0, 0, 0, 1.46) forwards" + tomlInputContainer.style.animation = UN_COLLAPSE + isCollapsed = false + collapseButton.textContent = "<" +} + + +collapseButton.onclick = function() { + if (!isCollapsed) { collapseInput(); } + else { unCollapseInput(); } +} + + +function loadingScreenCrafting() { + unCollapseInput(); +} + + +function drag_trees(mouse_offset) { + dragX = (mouseX - dragOffsetX) / scale + dragY = (mouseY - dragOffsetY) / scale + + trees.style.transform = `translate(${dragX}px, ${dragY}px)` +} +function on_start_drag() { + dragOffsetX = mouseX - dragX * scale + dragOffsetY = mouseY - dragY * scale + isDragging = true +} +function dragLoop() { + if (isDragging) { drag_trees() } + + requestAnimationFrame(dragLoop) +} + + +treeStatic.onmousedown = on_start_drag +document.addEventListener("mouseup", function() { isDragging = false }) +treeStatic.addEventListener("wheel", function(event) { + scale += (-event.deltaY / 500) + scale = Math.max(0.2, scale) + treeScale.style.transform = `scale(${scale})` +}) + +document.addEventListener("DOMContentLoaded", dragLoop) \ No newline at end of file diff --git a/toys/crafting/style.css b/toys/crafting/style.css new file mode 100644 index 0000000..7973e44 --- /dev/null +++ b/toys/crafting/style.css @@ -0,0 +1,84 @@ +.tomlInputContainer textarea { + font-family: "Roboto", sans-serif; + background-color: var(--navBarBtn_Inner); + box-shadow: calc(1px * var(--pxDensity)) 0px var(--navBarBtn_Border), + calc(-1px * var(--pxDensity)) 0px var(--navBarBtn_Border), + 0px calc(1px * var(--pxDensity)) var(--navBarBtn_Border), + 0px calc(-1px * var(--pxDensity)) var(--navBarBtn_Border); + + padding: calc(1px * var(--pxDensity)); + border: none; + font-size: min(5vmin, 1.2vmax, 0.9rem); + margin: calc(3px * var(--pxDensity)) 0% 0% 0%; + box-sizing: border-box; + width: calc(60px * var(--pxDensity)); + /*height: calc(100px * var(--pxDensity));*/ + height: 65vh; + color: inherit; + display: inline-block; + text-align: left; + resize: none +} +.tomlInputContainer textarea:hover { + filter: brightness(1.35); + cursor: pointer; +} + + +.tomlInputContainer label { + background-color: var(--navBarBtn_Inner); + box-shadow: calc(1px * var(--pxDensity)) 0px var(--navBarBtn_Border), + calc(-1px * var(--pxDensity)) 0px var(--navBarBtn_Border), + 0px calc(1px * var(--pxDensity)) var(--navBarBtn_Border), + 0px calc(-1px * var(--pxDensity)) var(--navBarBtn_Border); + + padding: calc(1px * var(--pxDensity)); + box-sizing: border-box; + width: round(auto, var(--pxDensity)); + height: calc(6px * var(--pxDensity)); + font-weight: 800; + text-align: center; +} + + +.tomlInputGrid { + display: grid; +} + + +.tomlInputContainer { + position: relative; + display: inline-flex; + margin: 0% auto 0% auto; + width: max-content; + max-height: 70vh; + padding: calc(2px * var(--pxDensity)); + max-width: min(600px, 100vw, 100vw); + font-size: min(1.5rem, calc(4px * var(--pxDensity))); + box-sizing: border-box; +} + + +#generateButton { + width: 100%; + height: calc(6px * var(--pxDensity)); +} + + +#collapseButton { + margin: 0% calc(3px * var(--pxDensity)); + height: calc(6px * var(--pxDensity)); + width: calc(6px * var(--pxDensity)); + aspect-ratio: 1 / 1; +} + + +@keyframes collapse { + 0% { transform: translateX(0%); } + 100% { transform: translateX(calc(-63px * var(--pxDensity))); } +} + +@keyframes un-collapse { + 0% { transform: translateX(calc(-63px * var(--pxDensity))); } + 100% { transform: translateX(0%); } +} \ No newline at end of file diff --git a/toys/crafting/tree.css b/toys/crafting/tree.css new file mode 100644 index 0000000..cfb4e64 --- /dev/null +++ b/toys/crafting/tree.css @@ -0,0 +1,85 @@ +#trees { + position: absolute; + left: 0%; + top: 0%; + width: max-content; + height: max-content; + padding: calc(16px * var(--pxDensity)) calc(2px * var(--pxDensity)); + overflow: visible; + display: flex; + flex-direction: column; + gap: calc(5px * var(--pxDensity)); + user-select: none; +} + +.tree { + display: inline-flex; + justify-content: center; + width: min-content; + height: min-content; + padding: calc(3px * var(--pxDensity)); + background-color: rgba(0.1, 0.1, 0.1, 0.1); + user-select: none; +} +.item { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + overflow: visible; + margin-bottom: calc(3px * var(--pxDensity)); + user-select: none; +} +.siblings { + display: flex; + justify-content: center; + gap: calc(3px * var(--pxDensity)); + align-items: flex-end; + background-color: rgba(0.1, 0.1, 0.1, 0.1); + padding: calc(2px * var(--pxDensity)); + margin-bottom: calc(3px * var(--pxDensity)); + user-select: none; +} + +.item p { /* from .encased */ + display: inline-block; + background-color: var(--navBarBtn_Inner); + box-shadow: calc(1px * var(--pxDensity)) 0px var(--navBarBtn_Border), + calc(-1px * var(--pxDensity)) 0px var(--navBarBtn_Border), + 0px calc(1px * var(--pxDensity)) var(--navBarBtn_Border), + 0px calc(-1px * var(--pxDensity)) var(--navBarBtn_Border); + + padding: calc(1px * var(--pxDensity)); + width: round(auto, var(--pxDensity)); + height: calc(3px * var(--pxDensity)); + border: none; + color: #ffffff; + font-size: min(5vmin, 1.2vmax, 0.9rem); + min-width: calc(12px * var(--pxDensity)); + text-align: center; + margin: 0; + user-select: none; +} +.item .blue { + background-color: var(--navBar_Inner); + box-shadow: calc(1px * var(--pxDensity)) 0px var(--navBar_Border), + calc(-1px * var(--pxDensity)) 0px var(--navBar_Border), + 0px calc(1px * var(--pxDensity)) var(--navBar_Border), + 0px calc(-1px * var(--pxDensity)) var(--navBar_Border); +} + + +#treeStaticContainer { + position: fixed; + top: 0%; + left: 0%; + width: 100vw; + height: 100vh; + display: inline-block; + cursor: grab; +} + +#treeScaleContainer { + width: 100vw; + height: 100vh; +} \ No newline at end of file diff --git a/toys/crafting/tree_generator.js b/toys/crafting/tree_generator.js new file mode 100644 index 0000000..b8fc2e0 --- /dev/null +++ b/toys/crafting/tree_generator.js @@ -0,0 +1,120 @@ +import { parse } from "https://esm.sh/smol-toml" + +let tomlInput = document.getElementById("tomlInput") +let genButton = document.getElementById("generateButton") +let trees = document.getElementById("trees") + +let recipes = {} +let startItems = [] +let products = [] + + +genButton.onclick = getDataFromInput + + +function getDataFromInput() { + let input = tomlInput.value + try { + let json = parse(input) + + startItems = json.io.inputs + products = json.io.products + recipes = json.recipes + } catch (e) { alert(e) } + + clearTrees() + + for (let product of products) { + console.log("generating: \"" + product + "\"") + genTreeForProduct(product) + } +} + + +function genTreeForProduct(product) { + let treeData = RecursivelyGetRecipes(product) + + let treeNode = document.createElement("div") + treeNode.className = "tree" + + makeTreeHTML(treeData, treeNode, true) + + trees.appendChild(treeNode) +} + + +function RecursivelyGetRecipes(product) { + let recipe = recipes[product] + + if (recipe == undefined) { + alert("ERROR: Recipe not found for \"" + product + "\"") + return [product] + } + + let children = [] + + for (let item of recipe) { + if (startItems.includes(item)) { children.push(item) } + else { children.push(...RecursivelyGetRecipes(item)) } + } + + return [product, children] +} + + +function prettyTreeString(tree, indent=0) { + let string = "" + + for (let item of tree) { + if (typeof item == "string") + { string += "| ".repeat(indent) + item + "\n" } + else { string += prettyTreeString(item, indent + 1) } + } + + return string +} + + +function clearTrees() { + let children = trees.children + for (let c of children) { c.remove() } +} + + +function makeTreeHTML(tree, parentNode, blue = false) { + let previouslyAdded = undefined + + let stringCount = tree.filter((x) => typeof(x) == "string").length + let arrCount = tree.length - stringCount + + // add .siblings container if theres more than 1 .item + if (stringCount > 1) { + let s = document.createElement("div") + s.className = "siblings" + parentNode.prepend(s) + parentNode = s + } + if (arrCount == 0) { blue = true } + + for (let i = 0; i < tree.length; i++) { + if (typeof(tree[i]) == "string") { + if (tree.length - 1 == i || tree[i + 1] == "string") { blue = true } + let n = makeItemNode(tree[i], blue) + parentNode.prepend(n) + previouslyAdded = n + } + else { makeTreeHTML(tree[i], previouslyAdded, false) } + } +} + + +function makeItemNode(name, blue = false) { + let node = document.createElement("div") + node.className = "item" + let p = document.createElement("p") + if (blue) { p.className = "blue" } + p.textContent = name + node.appendChild(p) + + return node +} \ No newline at end of file diff --git a/toys/index.html b/toys/index.html index 910c24f..45966f0 100644 --- a/toys/index.html +++ b/toys/index.html @@ -50,6 +50,15 @@
+
+ +
diff --git a/toys/style.css b/toys/style.css index c0e322e..46a26f6 100644 --- a/toys/style.css +++ b/toys/style.css @@ -36,7 +36,7 @@ h1 { margin: 0%; } button:hover { - filter: brightness(1.15) drop-shadow(0px calc(1px * var(--pxDensity)) rgba(0, 0, 0, 0.5)); + filter: brightness(1.15) drop-shadow(0px calc(2px * var(--pxDensity)) rgba(0, 0, 0, 0.5)); cursor: pointer; } button:active { @@ -44,7 +44,7 @@ button:active { transform: translateY(calc(1px * var(--pxDensity))); } .toyUl { - padding: calc(3px * var(--pxDensity)); + padding: 0% calc(3px * var(--pxDensity)); display: inline-flex; width: fit-content; justify-content: center;