seanrs97 seanrs97 - 28 days ago 17
Javascript Question

Why isn't my canvas object changing color after setInterval() is called?

I'm trying to get my canvas object to change color automatically every 0.25 seconds during an animation when the

setInterval()
but instead it changes every time I press a key down. Here is my code to execute the animation.

// Creating the shape
class Planet extends CompoundDrawable{
constructor(context,x = 0, y = 0, fillStyle = "#000", strokeStyle = "transparent", lineWidth = 0, deltas = new Map(), shapes = new Set()){
super(context,x,y,fillStyle,strokeStyle,lineWidth,deltas);

const mainPlanetShape = new Circle(context,0,0,fillStyle,strokeStyle,0,new Map(),80);
this.shapes.add(mainPlanetShape);

const largePlanetCrater = new Circle(context,randomBetween(-23,23),randomBetween(-23,23),"darkgrey","transparent",0,new Map(),11);
this.shapes.add(largePlanetCrater);

for(let i = 0; i < 7; i++){
const planetCrater = new Circle(context,randomBetween(-23,23),randomBetween(-24,24),"darkgrey","transparent",0,new Map(),randomBetween(3,6));

this.shapes.add(planetCrater);
}
}
}

// Placing the shape on Canvas and animating it
function startAnimationS(){
const animationSObjects = new Set();

const animationSPlanet = new Planet(context,-100,canvas.height/2,colourChanger(),"transparent",10,new Map());
// Context, x, y , fillStyle, strokeStyle, lineWIdth, new Map
animationSObjects.add(animationSPlanet);
//Setting up properties to animate
setTimeout(() =>
{
animationSPlanet.deltas.set("x",400);
animationSPlanet.deltas.set("angle",3);
}, 1000)
setTimeout(() =>
{
animationSPlanet.deltas.delete("x");
animationSPlanet.deltas.delete("fillStyle");
},4000)

// Perform the animation
function animationS(){
requestId = requestAnimationFrame(animationS);
context.clearRect(0,0,canvas.width,canvas.height);

const diffSeconds = (Date.now() - lastTime) / 1000;
lastTime = Date.now();

if(diffSeconds > 0){
for(const animationSObject of animationSObjects)
{
if(animationSObject.x >= canvas.width/2.2)
{
animationSObject.x = 10;
}
animationSObject.applyAnimation(diffSeconds);
animationSObject.draw();
}
}
}
animationS();
}

let counter = 0;
let intervalInterchange;
//Colour changing function
function colourChanger()
{
counter = counter - 10;

let colour1 = 110 - counter;
colour2 = 90 - counter;
colour3 = 50 - counter;
colour4 = 0.5;

let finalColour = "rgba(" + Math.round(colour1) + "," + Math.round(colour2) + "," + Math.round(colour3) + "," + Math.round(colour4) + ")";
return finalColour;
}
if(intervalInterchange === "undefined")
{
setInterval(colourChanger,250);
} else {
clearInterval(intervalInt);
intervalInt = undefined;
}

// Calling the function by the event 'keydown'
document.addEventListener("keydown", (e) => {
e.preventDefault();
stopAnimation();
if(e.keyCode > 64 && e.keyCode < 91){
if(e.keyCode == 83)
{
startAnimationS();
} else {
alert("Please enter a letter between A and Z");
}
});

Answer

You're dropping the return value of the colourChanger function. You can't expect the setInterval function to magically know what you want to use it for, so you need to do that yourself.

Instead of calling the colourChanger function directly in an interval, call an anonymus function and inside that change the color of the shape:

setInterval(function() {
    animationSPlanet.color = colourChanger(); // I still don't know how you store this thing's color.
}, 250);