diff --git a/index.html b/index.html index 63a278b..0875d00 100644 --- a/index.html +++ b/index.html @@ -25,7 +25,16 @@ - + + + diff --git a/index.js b/index.js index d4da91e..b2b45d2 100644 --- a/index.js +++ b/index.js @@ -46,6 +46,9 @@ editor.setValue(sessionStorage.getItem("code") ?? editor.getValue(), -1); const runButton = document.querySelector("#run-button"); const saveButton = document.querySelector("#save-button"); +const saveDropdown = document.querySelector("#save-dropdown"); +const saveJsButton = document.querySelector("#save-js"); +const saveHtmlButton = document.querySelector("#save-html"); const consoleCode = document.querySelector("#console-code"); const sessionSaveDebounce = new Debounce(1000); @@ -61,15 +64,81 @@ runButton.onclick = (ev) => { runButton.textContent = "⚙️ Running..."; }; +function downloadFile(content, mime, extension) { + const filename = prompt("Filename?"); + + const element = document.createElement("a"); + + element.href = `data:${mime};charset=utf-8,${encodeURIComponent(content)}`; + element.download = filename.endsWith(extension) ? filename : filename + extension; + element.style.display = "none"; + + document.body.appendChild(element); + + element.click(); + + document.body.removeChild(element); +} + +function minifyJs(code) { + return code + .replace(/[\s\n]+/g, " ") + .replace(/;\s+/g, ";"); +} saveButton.onclick = (ev) => { - const code = editor.getValue(); - const element = document.createElement("a"); - element.setAttribute("href", `data:text/javascript;charset=utf-8,${encodeURIComponent(code)}`); - const filename = prompt("Filename?") - element.setAttribute("download", filename.endsWith(".js") ? filename : `${filename}.js`); - element.style.display = "none"; - document.body.appendChild(element); - element.click(); - document.body.removeChild(element); + if (saveButton.classList.contains("active")) { + saveButton.classList.remove("active"); + + saveDropdown.style.display = "none"; + } else { + saveButton.classList.add("active"); + + saveDropdown.style.display = "block"; + } }; + +saveJsButton.onclick = (ev) => { + downloadFile(editor.getValue(), "text/javascript", ".js"); +}; + +saveHtmlButton.onclick = async (ev) => { + const js = editor.getValue().split("\n").map(line => " ".repeat(12) + line).join("\n"); + let lib = await (await fetch("./lib.js")).text(); + lib = minifyJs(lib); + + const html = ` + + + + + + Game + + + + + + + +`; + + downloadFile(html, "text/html", ".html"); +}; + diff --git a/lib.js b/lib.js index 582e588..1e14ca7 100644 --- a/lib.js +++ b/lib.js @@ -24,7 +24,10 @@ export function drawRect(x, y, width, height, color) { } export function println(msg) { - consoleCode.textContent += `${msg}\n`; + if (consoleCode) + consoleCode.textContent += `${msg}\n`; + else + console.log(msg); } export function startGameLoop(loopFunction) { diff --git a/style.css b/style.css index 1c4062b..d71954b 100644 --- a/style.css +++ b/style.css @@ -54,6 +54,7 @@ div#buttons { display: flex; flex: row; justify-content: space-between; + align-items: flex-start; gap: 5px; } @@ -129,6 +130,33 @@ div#buttons > * > button { font-size: 16px; } +.dropdown-wrapper { + position: relative; +} + +.dropdown-content { + display: none; + background-color: white; + position: absolute; + top: 100%; + left: 0; + right: 0; + border-radius: 4px; + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.1); +} + +.dropdown-option { + padding: 5px 10px; + font-family: sans-serif; + color: #424242; + font-size: 0.8rem; + cursor: pointer; +} + +.dropdown-option:hover { + background-color: #EEE; +} + button { background-color: #4FC3F7; border: none; @@ -139,6 +167,10 @@ button { transition-duration: 200ms; } +button.active { + background-color: #0288D1; +} + button:hover { box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.2); }