Use JSON templates for deck info
This commit is contained in:
parent
d12ab839aa
commit
13b3ed4c96
@ -17,12 +17,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form id="cardForm">
|
<form id="cardForm"></form>
|
||||||
<div><label> Name: <input type="text" id="cardName"> </label></div>
|
|
||||||
<div><label> Keywords: <input type="text" id="cardKeywords"> </label></div>
|
|
||||||
<div><label> Count: <input type="number" id="cardCount"> </label></div>
|
|
||||||
<div><label> Text: <textarea id="cardText"></textarea> </label></div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div id="deck"></div>
|
<div id="deck"></div>
|
||||||
</body>
|
</body>
|
||||||
|
110
js/editor.js
110
js/editor.js
@ -1,21 +1,15 @@
|
|||||||
let deckJSON;
|
let deckJSON, template;
|
||||||
let selected = 0;
|
let selected;
|
||||||
let deckName = window.location.pathname.split('/')[2];
|
let deckName = window.location.pathname.split('/')[2];
|
||||||
|
|
||||||
document.title = "Editor|" + deckName;
|
document.title = "Editor|" + deckName;
|
||||||
|
|
||||||
window.addEventListener("load", () => {
|
window.addEventListener("load", () => {
|
||||||
// load input json
|
// load deck input json
|
||||||
let xhr = new XMLHttpRequest();
|
getJSON("deck.input.json", json => {
|
||||||
xhr.addEventListener("load", () => {
|
deckJSON = json;
|
||||||
// if deck already has input json, load it
|
|
||||||
if (xhr.status === 200) {
|
|
||||||
deckJSON = JSON.parse(xhr.responseText);
|
|
||||||
makeSVGs(deckJSON);
|
makeSVGs(deckJSON);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
xhr.open("GET", "deck.input.json");
|
|
||||||
xhr.send();
|
|
||||||
|
|
||||||
// deck JSON uploader
|
// deck JSON uploader
|
||||||
document.querySelector('#jsonUpload').addEventListener('change', event => {
|
document.querySelector('#jsonUpload').addEventListener('change', event => {
|
||||||
@ -48,20 +42,39 @@ window.addEventListener("load", () => {
|
|||||||
// handle changes to card editor
|
// handle changes to card editor
|
||||||
document.querySelector('#cardForm').addEventListener('input', event => {
|
document.querySelector('#cardForm').addEventListener('input', event => {
|
||||||
let deck = document.querySelector('#deck');
|
let deck = document.querySelector('#deck');
|
||||||
let prop = event.target.id.substring(4).toLowerCase();
|
let prop = event.target.id.substring(5);
|
||||||
if (prop !== "count") {
|
if (prop === "image") {
|
||||||
wrapSVGText(deck.children[selected].querySelector('#' + prop),
|
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));
|
String(event.target.value));
|
||||||
}
|
}
|
||||||
if (event.target.value) {
|
if (event.target.value) {
|
||||||
deckJSON.deck[selected][prop] = event.target.value;
|
selected.json[prop] = event.target.value;
|
||||||
}
|
}
|
||||||
else {
|
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) {
|
function getSVGTemplate(name, callback) {
|
||||||
let xhr = new XMLHttpRequest();
|
let xhr = new XMLHttpRequest();
|
||||||
xhr.addEventListener("load", () => {
|
xhr.addEventListener("load", () => {
|
||||||
@ -77,33 +90,60 @@ function makeSVGs(deckJSON) {
|
|||||||
document.querySelector('#deckType').value = deckJSON.type || "";
|
document.querySelector('#deckType').value = deckJSON.type || "";
|
||||||
|
|
||||||
let deck = document.querySelector('#deck');
|
let deck = document.querySelector('#deck');
|
||||||
|
deck.innerHTML = "";
|
||||||
|
|
||||||
getSVGTemplate("environment/card", templateSVG => {
|
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)) *
|
deck.style.width = Math.ceil(Math.sqrt(deckJSON.deck.length)) *
|
||||||
parseInt(templateSVG.getAttribute("width")) + "pt";
|
parseInt(templateSVG.getAttribute("width")) + "pt";
|
||||||
deck.style.height = Math.ceil(Math.sqrt(deckJSON.deck.length)) *
|
deck.style.height = Math.ceil(Math.sqrt(deckJSON.deck.length)) *
|
||||||
parseInt(templateSVG.getAttribute("height")) + "pt";
|
parseInt(templateSVG.getAttribute("height")) + "pt";
|
||||||
|
|
||||||
deck.innerHTML = "";
|
|
||||||
|
|
||||||
// build card SVGs
|
// build card SVGs
|
||||||
deckJSON.deck.forEach((card, index) => {
|
deckJSON[cardType[0]].forEach(
|
||||||
let cardSVG = templateSVG.cloneNode(true);
|
card => makeCardSVG(deck, cardType[1], templateSVG, card));
|
||||||
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 || "";
|
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);
|
}, true);
|
||||||
deck.appendChild(cardSVG);
|
Object.keys(cardInputTemplate.inputs).forEach(prop =>
|
||||||
for (let prop in card) {
|
wrapSVGText(cardSVG.querySelector('#' + prop), String(card[prop] || "")));
|
||||||
if (prop !== "count") {
|
|
||||||
wrapSVGText(cardSVG.querySelector('#' + prop), String(card[prop]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function upload() {
|
function upload() {
|
||||||
|
@ -41,9 +41,10 @@ const server = http.createServer((req, res) => {
|
|||||||
switch (item) {
|
switch (item) {
|
||||||
case "card.json":
|
case "card.json":
|
||||||
case "deck.json":
|
case "deck.json":
|
||||||
|
case "environment/input.json":
|
||||||
sendFile(res, "template/" + item, 'application/json');
|
sendFile(res, "template/" + item, 'application/json');
|
||||||
break;
|
break;
|
||||||
case "environment/card.svg":
|
case "environment/deck.svg":
|
||||||
case "hero/card.svg":
|
case "hero/card.svg":
|
||||||
case "hero/charBack.svg":
|
case "hero/charBack.svg":
|
||||||
case "hero/charFront.svg":
|
case "hero/charFront.svg":
|
||||||
|
@ -332,6 +332,7 @@
|
|||||||
<path d="m138.51 151.36h-108.41v12.805h108.41zm-0.75 12.055h-106.91v-11.305h106.91z"/>
|
<path d="m138.51 151.36h-108.41v12.805h108.41zm-0.75 12.055h-106.91v-11.305h106.91z"/>
|
||||||
</g>
|
</g>
|
||||||
<text id="name" x="25.724066" y="30.655819" fill="url(#linear8)" font-family="'CrashLanding BB'" font-size="23px" width="100px" stroke="#000000" stroke-width=".7">Header</text>
|
<text id="name" x="25.724066" y="30.655819" fill="url(#linear8)" font-family="'CrashLanding BB'" font-size="23px" width="100px" stroke="#000000" stroke-width=".7">Header</text>
|
||||||
|
<image x="25.724066" y="30.655819" width="100px" height="100px" id="image"/>
|
||||||
<g fill="#000000" font-family="'RedStateBlueState BB'">
|
<g fill="#000000" font-family="'RedStateBlueState BB'">
|
||||||
<text id="keywords" x="84" y="160" text-anchor="middle" font-size="11.696px" font-weight="bold"> <tspan>Keywords</tspan> </text>
|
<text id="keywords" x="84" y="160" text-anchor="middle" font-size="11.696px" font-weight="bold"> <tspan>Keywords</tspan> </text>
|
||||||
<text id="text" x="27" y="170" font-size="10px" width="152px" height="50px" xml:space="preserve"> <tspan>Text Here</tspan> </text>
|
<text id="text" x="27" y="170" font-size="10px" width="152px" height="50px" xml:space="preserve"> <tspan>Text Here</tspan> </text>
|
Before Width: | Height: | Size: 276 KiB After Width: | Height: | Size: 276 KiB |
19
template/environment/input.json
Normal file
19
template/environment/input.json
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user