diff --git a/docs/src/gamelib/index.md b/docs/src/gamelib/index.md index cdbcf8d..f37229f 100644 --- a/docs/src/gamelib/index.md +++ b/docs/src/gamelib/index.md @@ -220,7 +220,7 @@ lib.startGameLoop(function () { `lib.drawSprite(x: number, y: number, width: number, height: number, name: string) -> void` -Draws a sprite imported in the sprite editor. +Draws a sprite imported in the asset editor. /* todo: link to sprite editor docs */ diff --git a/index.html b/index.html index ec08c6b..2beb65c 100644 --- a/index.html +++ b/index.html @@ -115,25 +115,25 @@ lib.startGameLoop(loop); -
-
+
+
-
+
- Sprite editor + Asset editor
-
-

- - +
+

+ +
-

Uploaded sprites

-
    - +

    Uploaded assets

    +
      +
      diff --git a/src/sprite_editor.js b/src/asset_editor.js similarity index 63% rename from src/sprite_editor.js rename to src/asset_editor.js index 2d480a8..45efb61 100644 --- a/src/sprite_editor.js +++ b/src/asset_editor.js @@ -1,13 +1,13 @@ import { promptUpload } from "./prompt_upload.js"; -export class SpriteEditor { +export class AssetEditor { constructor(rootEl) { - this.list = rootEl.querySelector("#sprite-editor-sprite-list"); - this.editor = rootEl.querySelector("#sprite-editor"); - this.toggleButton = rootEl.querySelector("#toggle-sprite-editor-button"); + this.list = rootEl.querySelector("#asset-editor-asset-list"); + this.editor = rootEl.querySelector("#asset-editor"); + this.toggleButton = rootEl.querySelector("#toggle-asset-editor-button"); this.container = rootEl; this.previewedId = null; - if (localStorage.getItem("sprite-editor-expanded")) { + if (localStorage.getItem("asset-editor-expanded")) { this.editor.style.display = "block"; this.container.style.flexGrow = "1"; this.toggleButton.innerHTML = "›"; @@ -15,22 +15,22 @@ export class SpriteEditor { } this.preview = {}; - this.preview.title = rootEl.querySelector("#sprite-editor-preview-title"); - this.preview.image = rootEl.querySelector("#sprite-editor-preview-image"); - this.preview.snippet = rootEl.querySelector("#sprite-editor-preview-snippet"); - this.sprites = []; + this.preview.title = rootEl.querySelector("#asset-editor-preview-title"); + this.preview.image = rootEl.querySelector("#asset-editor-preview-image"); + this.preview.snippet = rootEl.querySelector("#asset-editor-preview-snippet"); + this.assets = []; - rootEl.querySelector("#sprite-editor-upload-button").addEventListener("click", () => { + rootEl.querySelector("#asset-editor-upload-button").addEventListener("click", () => { this.promptUpload(); }); this.renderList(); } - importSprites(sprites) { - this.sprites = []; - for (const sprite of sprites) { - this.addSprite({ name: sprite.name, bytes: sprite.bytes, mime: sprite.mime }); + importAssets(assets) { + this.assets = []; + for (const asset of assets) { + this.addAsset({ name: asset.name, bytes: asset.bytes, mime: asset.mime }); } this.renderList(); } @@ -39,7 +39,7 @@ export class SpriteEditor { for (const file of await promptUpload("image/*", true)) { const rootName = file.name; let fullName = file.name; - for (let i = 0; this.sprites.some((x) => x.name === fullName); ++i) { + for (let i = 0; this.assets.some((x) => x.name === fullName); ++i) { const extensionIdx = rootName.split("").findLastIndex((x) => x === "."); let name = rootName; let extension = ""; @@ -49,7 +49,7 @@ export class SpriteEditor { } fullName = `${name}-${i}${extension}`; } - this.addSprite({ + this.addAsset({ name: fullName, mime: file.type, bytes: await fetch(URL.createObjectURL(file)).then((x) => x.bytes()), @@ -57,24 +57,24 @@ export class SpriteEditor { } } - addSprite({ name, bytes, mime }) { + addAsset({ name, bytes, mime }) { const id = Math.round(Math.random() * 1e6); - this.sprites.push({ id, bytes, name, mime }); + this.assets.push({ id, bytes, name, mime }); this.renderList(); } - deleteSprite(id) { - this.sprites = this.sprites.filter((x) => x.id !== id); + deleteAsset(id) { + this.assets = this.assets.filter((x) => x.id !== id); this.renderList(); } setPreview(id) { this.previewedId = id; - const sprite = this.sprites.find((x) => x.id === id); - this.preview.title.textContent = sprite.name; - this.preview.image.src = `data:${sprite.mime};base64,${sprite.bytes.toBase64()}`; + const asset = this.assets.find((x) => x.id === id); + this.preview.title.textContent = asset.name; + this.preview.image.src = `data:${asset.mime};base64,${asset.bytes.toBase64()}`; - const sanitizedName = sprite.name.replace(/" + " width, height,
      " + @@ -89,11 +89,11 @@ export class SpriteEditor { } renderList() { - const children = this.sprites - .map((sprite) => { + const children = this.assets + .map((asset) => { const listItem = document.createElement("li"); - listItem.classList.add("sprite-editor-list-item"); - if (this.previewedId === sprite.id) { + listItem.classList.add("asset-editor-list-item"); + if (this.previewedId === asset.id) { listItem.setAttribute("previewed", true); } listItem.addEventListener("click", () => { @@ -101,10 +101,10 @@ export class SpriteEditor { li.removeAttribute("previewed"); } listItem.setAttribute("previewed", true); - this.setPreview(sprite.id); + this.setPreview(asset.id); }); const name = document.createElement("span"); - name.textContent = sprite.name; + name.textContent = asset.name; listItem.append(name); const deleteButton = document.createElement("button"); deleteButton.innerHTML = "×"; @@ -114,7 +114,7 @@ export class SpriteEditor { if (listItem.getAttribute("previewed")) { this.clearPreview(); } - this.deleteSprite(sprite.id); + this.deleteAsset(asset.id); }); listItem.append(deleteButton); return listItem; @@ -124,18 +124,18 @@ export class SpriteEditor { } toggleEditor() { - if (!localStorage.getItem("sprite-editor-expanded")) { + if (!localStorage.getItem("asset-editor-expanded")) { this.editor.style.display = "block"; this.container.style.flexGrow = "1"; this.toggleButton.innerHTML = "›"; this.toggleButton.setAttribute("expanded", true); - localStorage.setItem("sprite-editor-expanded", true); + localStorage.setItem("asset-editor-expanded", true); } else { this.editor.style.display = "none"; this.container.style.flexGrow = "0"; this.toggleButton.innerHTML = "‹"; this.toggleButton.removeAttribute("expanded"); - localStorage.removeItem("sprite-editor-expanded"); + localStorage.removeItem("asset-editor-expanded"); } } } diff --git a/src/asset_provider.js b/src/asset_provider.js new file mode 100644 index 0000000..4018f78 --- /dev/null +++ b/src/asset_provider.js @@ -0,0 +1,27 @@ +export class AssetProvider { + constructor() { + this.assets = []; + } + + injectAssets(assets) { + this.assets = assets; + } + + url(name) { + const asset = this.assets.find((x) => x.name === name); + if (!asset) { + throw new Error(`Asset with name '${name}' does not exist`); + } + return `data:${asset.mime};base64,${asset.bytes.toBase64()}`; + } + + getAll() { + const result = {}; + + for (const asset of this.assets) { + result[asset.name] = this.url(asset.name); + } + + return result; + } +} diff --git a/src/gamelib.js b/src/gamelib.js index 4e5ebce..b29f455 100644 --- a/src/gamelib.js +++ b/src/gamelib.js @@ -3,10 +3,10 @@ export class Gamelib { keyPressHandlers = new Map(); keyReleaseHandlers = new Map(); - constructor(console, codeStopper, spriteProvider, canvasElement) { + constructor(console, codeStopper, assetProvider, canvasElement) { this.console = console; this.codeStopper = codeStopper; - this.spriteProvider = spriteProvider; + this.assetProvider = assetProvider; this.canvas = canvasElement; this.width = 480; @@ -80,7 +80,7 @@ export class Gamelib { const cx = this.cx; const image = new Image(); - image.src = this.spriteProvider.url(name); + image.src = this.assetProvider.url(name); image.onload = () => { cx.drawImage(image, x, y, width, height); }; diff --git a/src/gesundheit.js b/src/gesundheit.js index 4b4807f..cda32f2 100644 --- a/src/gesundheit.js +++ b/src/gesundheit.js @@ -1,27 +1,3 @@ -async function asyncIdbRequest(req) { - return await new Promise((resolve, reject) => { - req.onerror = () => { - reject(req.error); - }; - - req.onsuccess = () => { - resolve(req.result); - }; - }); -} - -const Idb = new Proxy(globalThis.indexedDB, { - get(target, prop, _receiver) { - if (typeof target[prop] === "function") { - return (...args) => { - const req = target[prop](...args); - return asyncIdbRequest(req); - }; - } - return Reflect.get(...arguments); - }, -}); - export class Gesundheit { static #isInternalConstructing = false; static #idb = globalThis.indexedDB; @@ -33,8 +9,25 @@ export class Gesundheit { Gesundheit.#isInternalConstructing = false; } - static async load(name) { - const db = await Idb.open(name); - console.log(db); + static load(name) { + this.#idb.deleteDatabase(name); + const req = this.#idb.open(name); + req.onerror = () => { + console.log("error", req.error); + }; + + req.onupgradeneeded = () => { + const db = req.result; + + const objectStore = db.createObjectStore("asset", { + keyPath: "filename", + }); + + console.log("upgrade pls", db); + }; + + req.onsuccess = () => { + console.log("success", req.result); + }; } } diff --git a/src/html_exporter.js b/src/html_exporter.js index 94f474b..1e86478 100644 --- a/src/html_exporter.js +++ b/src/html_exporter.js @@ -1,8 +1,8 @@ import { minifyJs } from "./utils.js"; export class HtmlExporter { - constructor(spriteProvider) { - this.spriteProvider = spriteProvider; + constructor(assetProvider) { + this.assetProvider = assetProvider; } async export(projectName, code) { @@ -13,7 +13,7 @@ export class HtmlExporter { let lib = await (await fetch("./src/gamelib.js")).text(); lib = minifyJs(lib); - const sprites = this.spriteProvider.getAll(); + const assets = this.assetProvider.getAll(); const html = ` @@ -41,15 +41,15 @@ export class HtmlExporter {