290 lines
8.9 KiB
JavaScript
290 lines
8.9 KiB
JavaScript
import init, {
|
|
add_room,
|
|
get_palettes,
|
|
get_preview,
|
|
load_image,
|
|
load_game,
|
|
load_default_game,
|
|
output,
|
|
set_brightness,
|
|
set_dither,
|
|
set_palette,
|
|
set_room_name,
|
|
} from './pkg/pixsy.js';
|
|
|
|
// stolen from https://ourcodeworld.com/articles/read/189/how-to-create-a-file-and-generate-a-download-with-javascript-in-the-browser-without-a-server
|
|
function download(filename, text) {
|
|
let element = document.createElement('a');
|
|
|
|
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
|
|
element.setAttribute('download', filename);
|
|
element.style.display = 'none';
|
|
document.body.appendChild(element);
|
|
element.click();
|
|
document.body.removeChild(element);
|
|
}
|
|
|
|
function copyToClipboard() {
|
|
const button = el("clipboard");
|
|
|
|
el("output").select();
|
|
document.execCommand("copy");
|
|
button.innerText = "copied!";
|
|
|
|
setTimeout(() => {
|
|
button.innerText = "copy to clipboard";
|
|
}, 2000);
|
|
}
|
|
|
|
function el(id) {
|
|
return document.getElementById(id);
|
|
}
|
|
|
|
function pagination(e) {
|
|
const parent = e.target.parentNode;
|
|
|
|
parent.style.display = "none";
|
|
|
|
if (e.target.classList.contains("next")) {
|
|
parent.nextSibling.style.display = "block";
|
|
} else if (e.target.classList.contains("prev")) {
|
|
parent.previousSibling.style.display = "block";
|
|
} else if (e.target.classList.contains("start")) {
|
|
document.getElementById("start").style.display = "block";
|
|
}
|
|
}
|
|
|
|
function readFile(input, callback, type = "text") {
|
|
if (input.files && input.files[0]) {
|
|
let reader = new FileReader();
|
|
reader.onload = callback;
|
|
|
|
if (type === "text") {
|
|
reader.readAsText(input.files[0]);
|
|
} else {
|
|
reader.readAsDataURL(input.files[0]);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function run() {
|
|
if (typeof WebAssembly !== "object") {
|
|
window.location = "http://tinybird.info/image-to-bitsy/old/"
|
|
}
|
|
|
|
await init();
|
|
|
|
const buttonAddImage = el("add");
|
|
const buttonBackToImage = el("back-to-image");
|
|
const buttonCopyToClipboard = el("clipboard")
|
|
const buttonDownload = el("download");
|
|
const buttonGameDataProceed = el("game-data-next");
|
|
const buttonImageProceed = el("image-next");
|
|
const buttonRoomProceed = el("room-next");
|
|
const buttonLoadGame = el("load");
|
|
const buttonNewGame = el("new");
|
|
const buttonReset = el("reset");
|
|
const checkboxDither = el("dither");
|
|
const divCroppie = el("crop");
|
|
const divNewPalette = el("new-palette");
|
|
const inputBrightness = el("brightness");
|
|
const inputColourBackground = el("colour-background");
|
|
const inputColourForeground = el("colour-foreground");
|
|
const inputRoomName = el("room-name");
|
|
const selectPalette = el("palette");
|
|
const textareaGameDataInput = el("game-data");
|
|
const textareaGameDataOutput = el("output");
|
|
|
|
const croppie = new Croppie(divCroppie, {
|
|
viewport: {width: 128, height: 128, type: 'square'},
|
|
boundary: {width: 256, height: 256},
|
|
enableZoom: true,
|
|
});
|
|
|
|
// hide all pages except start page
|
|
for (let page of document.getElementsByClassName('page')) {
|
|
page.style.display = "none";
|
|
}
|
|
el("start").style.display = "block";
|
|
|
|
for (let pageButton of document.getElementsByClassName("pagination")) {
|
|
pageButton.addEventListener('click', pagination);
|
|
pageButton.addEventListener('touchend', pagination);
|
|
}
|
|
|
|
// croppie needs to be on screen to work;
|
|
// halt pagination until we're finished gathering the results
|
|
buttonImageProceed.removeEventListener("click", pagination);
|
|
|
|
function new_game() {
|
|
load_default_game();
|
|
textareaGameDataInput.value = output();
|
|
checkGameData();
|
|
// we don't need to look at the default game data, so skip ahead to the image page
|
|
buttonGameDataProceed.click();
|
|
}
|
|
|
|
function clear_game() {
|
|
textareaGameDataInput.value = "";
|
|
checkGameData();
|
|
}
|
|
|
|
buttonNewGame.addEventListener("click", new_game);
|
|
buttonNewGame.addEventListener("touchend", new_game);
|
|
buttonLoadGame.addEventListener("click", clear_game);
|
|
buttonLoadGame.addEventListener("touchend", clear_game);
|
|
|
|
// handle game data and image
|
|
|
|
el("game").addEventListener("change", function() {
|
|
readFile(this, function (e) {
|
|
textareaGameDataInput.value = e.target.result;
|
|
checkGameData();
|
|
}, "text");
|
|
});
|
|
|
|
function setPaletteDropdown() {
|
|
const palettes = JSON.parse(get_palettes());
|
|
|
|
selectPalette.innerHTML = "";
|
|
|
|
palettes.push({
|
|
id: "NEW_PALETTE",
|
|
name: "new palette"
|
|
});
|
|
|
|
for (let palette of palettes) {
|
|
let option = document.createElement("option");
|
|
|
|
option.value = palette.id;
|
|
option.innerText = palette.name;
|
|
|
|
selectPalette.appendChild(option);
|
|
}
|
|
}
|
|
|
|
function checkGameData() {
|
|
let result = load_game(textareaGameDataInput.value)
|
|
|
|
if (result === "Loaded game") {
|
|
buttonGameDataProceed.removeAttribute("disabled");
|
|
setPaletteDropdown();
|
|
} else {
|
|
buttonGameDataProceed.setAttribute("disabled", "disabled");
|
|
}
|
|
}
|
|
|
|
textareaGameDataInput.addEventListener("change", checkGameData);
|
|
textareaGameDataInput.addEventListener("keyup", checkGameData);
|
|
checkGameData();
|
|
|
|
el('image').addEventListener('change', function () {
|
|
readFile(this, function (e) {
|
|
croppie.bind({url: e.target.result, zoom: 0});
|
|
divCroppie.style.display = "block";
|
|
buttonImageProceed.removeAttribute("disabled");
|
|
}, "image");
|
|
});
|
|
|
|
function loadPreview() {
|
|
el("preview").setAttribute("src", get_preview());
|
|
}
|
|
|
|
function handleImage() {
|
|
croppie.result({
|
|
type: "base64",
|
|
size: "viewport",
|
|
format: "png",
|
|
}).then((result) => {
|
|
console.log("Loading image: " + load_image(result));
|
|
|
|
el("page-image").style.display = "none";
|
|
el("page-room" ).style.display = "block";
|
|
|
|
loadPreview();
|
|
});
|
|
}
|
|
|
|
buttonImageProceed.addEventListener("click", handleImage);
|
|
buttonImageProceed.addEventListener("touchend", handleImage);
|
|
|
|
selectPalette.addEventListener("change", () => {
|
|
set_palette(selectPalette.value, inputColourBackground.value, inputColourForeground.value);
|
|
|
|
if (selectPalette.value === "NEW_PALETTE") {
|
|
divNewPalette.style.display = "block";
|
|
} else {
|
|
divNewPalette.style.display = "none";
|
|
}
|
|
|
|
loadPreview();
|
|
});
|
|
|
|
function updateCustomPalette() {
|
|
set_palette(selectPalette.value, inputColourBackground.value, inputColourForeground.value);
|
|
loadPreview();
|
|
}
|
|
|
|
inputColourForeground.addEventListener("change", updateCustomPalette);
|
|
inputColourBackground.addEventListener("change", updateCustomPalette);
|
|
|
|
checkboxDither.addEventListener("change", () => {
|
|
set_dither(checkboxDither.checked);
|
|
loadPreview();
|
|
});
|
|
|
|
inputRoomName.addEventListener("change", () => {
|
|
set_room_name(inputRoomName.value);
|
|
});
|
|
|
|
inputBrightness.addEventListener("input", () => {
|
|
set_brightness(inputBrightness.value);
|
|
loadPreview();
|
|
});
|
|
|
|
function addRoom() {
|
|
el("added").innerText = add_room();
|
|
textareaGameDataOutput.value = output();
|
|
}
|
|
|
|
buttonRoomProceed.addEventListener("click", addRoom);
|
|
buttonRoomProceed.addEventListener("touchend", addRoom);
|
|
|
|
function handleDownload() {
|
|
download("output.bitsy", textareaGameDataOutput.value);
|
|
}
|
|
|
|
buttonCopyToClipboard.addEventListener("click", copyToClipboard);
|
|
buttonCopyToClipboard.addEventListener("touchend", copyToClipboard);
|
|
|
|
buttonDownload.addEventListener("click", handleDownload);
|
|
buttonDownload.addEventListener("touchend", handleDownload);
|
|
|
|
function addImage() {
|
|
textareaGameDataInput.value = textareaGameDataOutput.value;
|
|
textareaGameDataOutput.value = "";
|
|
buttonBackToImage.click();
|
|
}
|
|
|
|
buttonAddImage.addEventListener("click", addImage);
|
|
buttonAddImage.addEventListener("touchend", addImage);
|
|
|
|
// would it be easier just to reload the page? lol
|
|
function reset() {
|
|
clear_game();
|
|
// todo clear file inputs
|
|
inputBrightness.value = 0;
|
|
inputRoomName.value = "";
|
|
selectPalette.innerHTML = "";
|
|
divNewPalette.style.display = "none";
|
|
inputColourBackground.value = "#000000";
|
|
inputColourForeground.value = "#ffffff";
|
|
checkboxDither.checked = true;
|
|
}
|
|
|
|
buttonReset.addEventListener("click", reset);
|
|
buttonReset.addEventListener("touchend", reset);
|
|
}
|
|
|
|
run();
|