From 8d511a18be04e52d9b2984dc7c6f8946a5ed4a3f Mon Sep 17 00:00:00 2001 From: Adam Goldsmith Date: Sun, 8 Oct 2017 22:07:22 -0400 Subject: [PATCH] Use JSON templates for deck info --- html/editor.html | 7 +- js/editor.js | 120 +++++++++++++------- server.js | 3 +- template/environment/{card.svg => deck.svg} | 1 + template/environment/input.json | 19 ++++ 5 files changed, 103 insertions(+), 47 deletions(-) rename template/environment/{card.svg => deck.svg} (99%) create mode 100644 template/environment/input.json diff --git a/html/editor.html b/html/editor.html index b7c4aa8..ec20553 100644 --- a/html/editor.html +++ b/html/editor.html @@ -17,12 +17,7 @@ -
-
-
-
-
-
+
diff --git a/js/editor.js b/js/editor.js index 9c810f1..000965d 100644 --- a/js/editor.js +++ b/js/editor.js @@ -1,21 +1,15 @@ -let deckJSON; -let selected = 0; +let deckJSON, template; +let selected; let deckName = window.location.pathname.split('/')[2]; document.title = "Editor|" + deckName; window.addEventListener("load", () => { - // load input json - let xhr = new XMLHttpRequest(); - xhr.addEventListener("load", () => { - // if deck already has input json, load it - if (xhr.status === 200) { - deckJSON = JSON.parse(xhr.responseText); - makeSVGs(deckJSON); - } + // load deck input json + getJSON("deck.input.json", json => { + deckJSON = json; + makeSVGs(deckJSON); }); - xhr.open("GET", "deck.input.json"); - xhr.send(); // deck JSON uploader document.querySelector('#jsonUpload').addEventListener('change', event => { @@ -48,20 +42,39 @@ window.addEventListener("load", () => { // handle changes to card editor document.querySelector('#cardForm').addEventListener('input', event => { let deck = document.querySelector('#deck'); - let prop = event.target.id.substring(4).toLowerCase(); - if (prop !== "count") { - wrapSVGText(deck.children[selected].querySelector('#' + prop), + let prop = event.target.id.substring(5); + if (prop === "image") { + let files = event.target.files; + let reader = new FileReader(); + reader.onload = e => { + selected.svg.querySelector('#' + prop).setAttribute("href", e.target.result); + }; + reader.readAsDataURL(files[0]); + } + else if (prop !== "count") { + wrapSVGText(selected.svg.querySelector('#' + prop), String(event.target.value)); } if (event.target.value) { - deckJSON.deck[selected][prop] = event.target.value; + selected.json[prop] = event.target.value; } else { - delete deckJSON.deck[selected][prop]; + delete selected.json[prop]; } }); }); +function getJSON(filename, callback) { + let xhr = new XMLHttpRequest(); + xhr.addEventListener("load", () => { + if (xhr.status === 200) { + callback(JSON.parse(xhr.responseText)); + } + }); + xhr.open("GET", filename); + xhr.send(); +} + function getSVGTemplate(name, callback) { let xhr = new XMLHttpRequest(); xhr.addEventListener("load", () => { @@ -77,35 +90,62 @@ function makeSVGs(deckJSON) { document.querySelector('#deckType').value = deckJSON.type || ""; let deck = document.querySelector('#deck'); + deck.innerHTML = ""; - getSVGTemplate("environment/card", templateSVG => { - deck.style.width = Math.ceil(Math.sqrt(deckJSON.deck.length)) * - parseInt(templateSVG.getAttribute("width")) + "pt"; - deck.style.height = Math.ceil(Math.sqrt(deckJSON.deck.length)) * - parseInt(templateSVG.getAttribute("height")) + "pt"; + setDeckTemplate(deckJSON.type, () => { + Object.entries(template.cardTypes).forEach(cardType => { + getSVGTemplate(deckJSON.type + "/" + cardType[0], templateSVG => { + deck.style.width = Math.ceil(Math.sqrt(deckJSON.deck.length)) * + parseInt(templateSVG.getAttribute("width")) + "pt"; + deck.style.height = Math.ceil(Math.sqrt(deckJSON.deck.length)) * + parseInt(templateSVG.getAttribute("height")) + "pt"; - deck.innerHTML = ""; - - // build card SVGs - deckJSON.deck.forEach((card, index) => { - let cardSVG = templateSVG.cloneNode(true); - cardSVG.addEventListener('click', event => { - selected = index; - document.querySelector('#cardName').value = card.name || ""; - document.querySelector('#cardKeywords').value = card.keywords || ""; - document.querySelector('#cardCount').value = card.count || 1; - document.querySelector('#cardText').value = card.text || ""; - }, true); - deck.appendChild(cardSVG); - for (let prop in card) { - if (prop !== "count") { - wrapSVGText(cardSVG.querySelector('#' + prop), String(card[prop])); - } - } + // build card SVGs + deckJSON[cardType[0]].forEach( + card => makeCardSVG(deck, cardType[1], templateSVG, card)); + }); }); }); } +function setDeckTemplate(type, callback) { + getJSON("/template/" + type + "/input.json", json => { + template = json; + callback(); + }); +} + +function setForm(cardTemplate, card) { + let form = document.querySelector('#cardForm'); + form.innerHTML = ""; + + Object.entries(cardTemplate.inputs).forEach(prop => { + let div = form.appendChild(document.createElement('div')); + let label = div.appendChild(document.createElement('label')); + label.textContent = prop[0]; + + let input = label.appendChild(document.createElement('input')); + input.id = "card-" + prop[0]; + if (prop[1] === "image") { + input.type = "file"; + } + else { + input.type = prop[1]; + input.value = card[prop[0]] || ""; + } + }); +} + +function makeCardSVG(deck, cardInputTemplate, templateSVG, card) { + let cardSVG = deck.appendChild(templateSVG.cloneNode(true)); + cardSVG.addEventListener('click', () => { + selected = {svg: cardSVG, json: card}; + setForm(cardInputTemplate, card); + }, true); + Object.keys(cardInputTemplate.inputs).forEach(prop => + wrapSVGText(cardSVG.querySelector('#' + prop), String(card[prop] || ""))); +} + function upload() { let deck = document.querySelector('#deck'); diff --git a/server.js b/server.js index f9312fc..c1386e1 100644 --- a/server.js +++ b/server.js @@ -41,9 +41,10 @@ const server = http.createServer((req, res) => { switch (item) { case "card.json": case "deck.json": + case "environment/input.json": sendFile(res, "template/" + item, 'application/json'); break; - case "environment/card.svg": + case "environment/deck.svg": case "hero/card.svg": case "hero/charBack.svg": case "hero/charFront.svg": diff --git a/template/environment/card.svg b/template/environment/deck.svg similarity index 99% rename from template/environment/card.svg rename to template/environment/deck.svg index a03491b..754cf2a 100644 --- a/template/environment/card.svg +++ b/template/environment/deck.svg @@ -332,6 +332,7 @@ Header + Keywords Text Here diff --git a/template/environment/input.json b/template/environment/input.json new file mode 100644 index 0000000..1c08284 --- /dev/null +++ b/template/environment/input.json @@ -0,0 +1,19 @@ +{ + "cardTypes": { + "deck": { + "inputs": { + "name": "text", + "keywords": "text", + "text": "text", + "flavor": "text", + "artist": "text", + "hp": "number", + "image": "image" + }, + "hide": { + "hpMark": "hp", + "keywordBox": "keywords" + } + } + } +}