I am working on a character creator. You select different costumes from the form on the left and then the canvas on the right changes to reflect them. I am having an issue with costumes changing on form change. Here is the demo website: https://elegant-bonbon-6a82f0.netlify.app/
Currently, you can only make an image show up if the color is changed. Both onchange="" functions for select and color types run the same code (select form elements go through an if-then statement first and the call updatec). At first I thought it was an issue with the code adding the image to the canvas before the image loads, but that is not the case. I added a promise to wait for the image to load (My knowledge of promises is minimal, so I may have done something wrong).
Here's a demo what I am trying to accomplish: https://jasmine-mogadam.github.io/ This uses a setInterval loop that updates the canvas every few milliseconds. This issue with this is the more elements in the character creator, the more laggy the site becomes (also the setInterval loop no longer works for the first/netlify demo. That's another issue).
In summary, I'm trying to figure out what is different between my color updatec() and select update(). Why does color update the canvas correctly, but not the select elements?
HTML Form Snippet:
<form>
<label for="Shape">Shape:</label>
<select id="Shape" name="Shape" onchange="update(0, 'Circle,Square,Triangle')">
<option value="Circle">Circle</option>
<option value="Square">Square</option>
<option value="Triangle">Triangle</option>
</select>
<label for="color0">Shape Color:</label>
<input type="color" value="#B3B3B3" id="color0" name="Shape Color" onchange="updatec(0)"></div>
</form>
Functions
function colorCanvasImage(canvas,id) {
canvas.width = 500;
canvas.height = 500;
var context = canvas.getContext('2d');
var image = document.getElementById('image' + id);
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
// Set the canvas the same width and height of the image
//updates color every 10 miliseconds
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0, 0);
changeToColor(imageData.data,id);
context.putImageData(imageData, 0, 0);
console.log("Painting " + image.src);
loadImage(image.src).then(addEffect(id,context,canvas,image));
addEffect(id,context,canvas,image)
//let loop = setInterval(addEffect(id,context,canvas,image), 100);
}
//function drawImage(image,canvas,id) {
function drawImage(canvas,id) {
var context = canvas.getContext('2d');
var image = document.getElementById('image' + id);
//loadImage(image)
console.log("Drawing " + image.src);
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0, 0);
}
function addEffect(id,context,canvas,image) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0, 0);
var image = document.getElementById('image' + id);
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
changeToColor(imageData.data,id);
context.putImageData(imageData, 0, 0);
}
//function credit - https://stackoverflow.com/questions/21646738/convert-hex-to-rgba
function hexToRGB(hex, alpha) {
var r = parseInt(hex.slice(1, 3), 16),
g = parseInt(hex.slice(3, 5), 16),
b = parseInt(hex.slice(5, 7), 16);
if (alpha) {
return {r,g,b,alpha};
} else {
return [r,g,b];
}
}
function changeToColor(data,id) {
const colors = hexToRGB(document.getElementById("color"+id).value,false);
for (var i = 0; i < data.length; i+=4 ) {
if(data[i]!=0||data[i+3]==0){
data[i] = colors[0];
data[i+1] = colors[1];
data[i+2] = colors[2];
}
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function loadImage(url) {
return new Promise(resolve => {
image = new Image();
image.addEventListener('load', () => {
resolve(image);
});
image.src = url;
});
}
function update(id,list){
let costumes = list.split(",");
var canvas = document.getElementById("canvas"+id);
var object = document.getElementById("form").elements[id*2].value;
var image;
console.log("Selected: " + object);
costumes.forEach(costume =>{
if(object === costume){
document.getElementById("image"+id).src = costume + ".PNG";
image = costume + ".PNG";
}
});
updatec(id);
}
function updatec(id){
var canvas = document.getElementById("canvas"+id);
colorCanvasImage(canvas,id)
}
Thanks for reading and I hope you have a great day :)