From ed6a9097ee37a720a314148a72da59364e2d097c Mon Sep 17 00:00:00 2001 From: Vftdan Date: Tue, 23 Apr 2024 04:25:13 +0200 Subject: [PATCH] Refactored by moving common logic into PartHandler classes --- index.html | 8 +- neomojimixer.js | 543 ++++++++++++++++++++---------------------------- 2 files changed, 225 insertions(+), 326 deletions(-) diff --git a/index.html b/index.html index 2e2b5bd..ed2d43e 100644 --- a/index.html +++ b/index.html @@ -18,10 +18,10 @@
-
name body
-
name eyes
-
name mouth
-
name arms
+
name body
+
name eyes
+
name mouth
+
name arms
diff --git a/neomojimixer.js b/neomojimixer.js index 619dc80..680e512 100644 --- a/neomojimixer.js +++ b/neomojimixer.js @@ -1,52 +1,179 @@ const NeomojiMixer = (function(NeomojiMixer) { //global variables - //Arrays to hold the parts - let eyes = []; - let body = []; - let mouth = []; - let arms = []; - - //FOr all the different colours of the arms there will be each a own arraz - let arms_orange = []; - let arms_blue = []; - let arms_lightgrey = []; - let arms_red = []; - let arms_white = []; - let arms_yellow = []; - - //Index to easily find when to roll back to the first/last element in the list - let inex_eyes = 0; - let index_body = 0; - let index_mouth = 0; - let index_arms = 0; - let index_color = 0; + const color_names = [ + "blue", + "lightgrey", + "orange", + "red", + "white", + "yellow", + ]; + let selected_color = "blue"; + let color_change_callbacks = []; //shotnames for HTML elements to interact with - //images - const body_image = document.getElementById("body_img"); - const eyes_image = document.getElementById("eyes_img"); - const mouth_image = document.getElementById("mouth_img"); - const arms_image = document.getElementById("arms_img"); - const canvas = document.getElementById("canvas_export"); const export_img = document.getElementById("imageExport"); const neomoji_name = document.getElementById("fullNeomojiName"); - //names - const body_name = document.getElementById("body_name"); - const eyes_name = document.getElementById("eyes_name"); - const mouth_name = document.getElementById("mouth_name"); - const arms_name = document.getElementById("arms_name"); - //Stats const stats = document.getElementById("stats"); + function onColorChange() { + for (let i = 0; i < color_change_callbacks.length; i++) { + if (color_change_callbacks[i]) { + color_change_callbacks[i](); + } + } + } + + function PartHandler(name) { + this.name = name; + this.entries = []; //Arrays to hold the parts + this.entry_indices = []; //Maps selected_index to entries index + this.selected_index = 0; //index_color -> arms.selected_index; index_arms -> arms.entry_indices[arms.selected_index] + this.image_element = document.getElementById(name + "_img"); + this.name_element = document.getElementById(name + "_name"); + this.button_left = document.getElementById(name + "_left"); + this.button_right = document.getElementById(name + "_right"); + } + + PartHandler.prototype = { + fillArray: function(item) { + let name = item.name; + let url = item.url; + this.entries.push([name, url]); //Two dimensional array, Second dimension holds name on index 0 and url at index 1 + }, + fillIndices: function() { + for (let i = 0; i < this.entries.length; i++) { + this.entry_indices.push(i); //By default preserve index + } + }, + getSelectedEntry: function() { + return this.entries[this.entry_indices[this.selected_index]]; + }, + setIndex: function(index) { + const modulo = this.entry_indices.length; //Check if index is too big for the array + if (!modulo) { + this.selected_index = 0; //Error + } else { + index %= modulo; + if (index < 0) { + index += modulo; + } + this.selected_index = index; + } + this.redraw(); + }, + redraw: function() { + const entry = this.getSelectedEntry(); + this.image_element.src = "." + entry[1]; //Change URL of picture + this.name_element.innerHTML = entry[0]; //Change name in controls + }, + onClickNext: function() { + this.setIndex(this.selected_index + 1); + }, + onClickPrev: function() { + this.setIndex(this.selected_index - 1); + }, + activateControls: function() { + this.button_left.disabled = false; + this.button_right.disabled = false; + }, + randomize: function() { + this.setIndex(Math.floor(Math.random() * this.entry_indices.length)); + }, + createExportImage: function() { + const entry = this.getSelectedEntry(); + let img = new Image(); + img.src = "." + entry[1]; + return img; + }, + }; + + function ColoredPartHandler(name) { + PartHandler.call(this, name); + //For all the different colours of the arms there will be each a own array + this.colored_indices = Object.create(null); + for (let i = 0; i < color_names.length; i++) { + this.colored_indices[color_names[i]] = []; + } + this.entry_indices = this.colored_indices[selected_color]; + const that = this; + color_change_callbacks.push(function() { + that.onColorChange(); + }); + } + + ColoredPartHandler.prototype = Object.assign(Object.create(PartHandler.prototype), { + constructor: PartHandler, + fillArray: function(item) { + let name = item.name; + let url = item.url; + let color = item.color; + this.entries.push([name, url, color]); //Two dimensional array, Second dimension holds name on index 0, url at index 1, and color at index 2 + }, + fillIndices: function() { + for (let i = 0; i < this.entries.length; i++) { + const color = this.entries[i][2]; + if (color == "") { + //All colors + for (let j in this.colored_indices) { + this.colored_indices[j].push(i); + } + } else { + const indices = this.colored_indices[color]; + if (indices == undefined) { + console.log("Cannot register " + this.name + " with unknown color: " + color); + } else { + indices.push(i); + } + } + } + }, + onColorChange: function() { + this.entry_indices = this.colored_indices[selected_color]; + this.redraw(); + }, + }); + + function BodyPartHandler(name) { + PartHandler.call(this, name); + } + + BodyPartHandler.prototype = Object.assign(Object.create(PartHandler.prototype), { + constructor: PartHandler, + fillArray: ColoredPartHandler.prototype.fillArray, + setIndex: function(index) { + const modulo = this.entry_indices.length; //Check if index is too big for the array + if (!modulo) { + this.selected_index = 0; //Error + } else { + index %= modulo; + if (index < 0) { + index += modulo; + } + this.selected_index = index; + } + this.redraw(); + const entry = this.getSelectedEntry(); + selected_color = entry[2]; //Global + onColorChange(); //Global + }, + }); + + const part_handlers = { + body: new BodyPartHandler("body"), + eyes: new PartHandler("eyes"), + mouth: new PartHandler("mouth"), + arms: new ColoredPartHandler("arms"), + }; + // Loading the JSON and getting all the available parts async function getData() { - fetch('./parts.json') .then(function(response) { return response.json(); @@ -61,273 +188,41 @@ const NeomojiMixer = (function(NeomojiMixer) { function loadParts(parts) { //Load parts into Arrays - parts.type.eyes.forEach(fillArrayEyes); - parts.type.body.forEach(fillArrayBody); - parts.type.mouth.forEach(fillArrayMouth); - parts.type.arms.forEach(fillArrayArms); + for (const i in part_handlers) { + parts.type[i].forEach(function(p) {part_handlers[i].fillArray(p);}); + } //find the indexes of each part of the corresponding color and write those into the color arrays - fillArraysArms(); + for (const i in part_handlers) { + part_handlers[i].fillIndices(); + } //Randomize initial view randomize(); //Show little statistic - var sum = body.length + eyes.length + mouth.length + arms.length; - var variety = body.length * eyes.length * mouth.length * arms_orange.length; + var sum = 0; + var variety = 1; + for (const i in part_handlers) { + sum += part_handlers[i].entries.length; + variety *= part_handlers[i].entry_indices.length; + } stats.innerHTML = "There are " + sum + " Elements available,
with " + new Intl.NumberFormat("de-DE").format(variety) + " possible combinations."; //Activate the buttons after everything is loaded in - document.getElementById("body_left").disabled = false; - document.getElementById("body_right").disabled = false; - document.getElementById("eyes_left").disabled = false; - document.getElementById("eyes_right").disabled = false; - document.getElementById("mouth_left").disabled = false; - document.getElementById("mouth_right").disabled = false; - document.getElementById("arms_left").disabled = false; - document.getElementById("arms_right").disabled = false; + for (const i in part_handlers) { + part_handlers[i].activateControls(); + } document.getElementById("random").disabled = false; document.getElementById("export").disabled = false; } - function fillArrayEyes(item) { - let name = item.name; - let url = item.url; - eyes.push ([name, url]); //Two dimensional array, Second dimension holds name on index 0 and url at index 1 - } - - function fillArrayBody(item) { - let name = item.name; - let url = item.url; - let color = item.color; - body.push ([name, url, color]); //Two dimensional array, Second dimension holds name on index 0 and url at index 1 - } - - function fillArrayMouth(item) { - let name = item.name; - let url = item.url; - mouth.push ([name, url]); //Two dimensional array, Second dimension holds name on index 0 and url at index 1 - } - - function fillArrayArms(item) { - let name = item.name; - let url = item.url; - let color = item.color; - arms.push ([name, url, color]); //Two dimensional array, Second dimension holds name on index 0 and url at index 1 - } - - function fillArraysArms() { - for (let i=0; i