export class SpriteEditor { constructor(rootEl, sprites) { this.list = rootEl.querySelector("#sprite-editor-sprite-list"); this.preview = {}; this.preview.title = rootEl.querySelector("#sprite-editor-preview-title"); this.preview.image = rootEl.querySelector("#sprite-editor-preview-image"); this.sprites = sprites; rootEl.querySelector("#sprite-editor-upload-button").addEventListener("click", () => { this.promptUpload(); }); this.renderList(); } promptUpload() { const input = document.createElement("input"); input.type = "file"; input.accept = "image/*"; input.multiple = true; input.style = "display: none;"; input.addEventListener("cancel", () => { input.remove(); }); input.addEventListener("change", async () => { for (const file of input.files) { this.addSprite({ name: file.name, mime: file.type, bytes: await fetch(URL.createObjectURL(file)).then((x) => x.bytes()), }); } input.remove(); }); document.body.append(input); input.click(); } addSprite({ name, bytes, mime }) { const id = Math.round(Math.random() * 1e6); this.sprites.push({ id, bytes, name, mime }); this.renderList(); } deleteSprite(id) { this.sprites = this.sprites.filter((x) => x.id !== id); this.renderList(); } setPreview(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()}`; } renderList() { const children = this.sprites .map((sprite) => { const listItem = document.createElement("li"); listItem.classList.add("sprite-editor-list-item"); const name = document.createElement("span"); name.textContent = sprite.name; name.addEventListener("click", () => { this.setPreview(sprite.id); }); listItem.append(name); return listItem; }); this.list.replaceChildren(...children); } }