user8716582
user8716582

Reputation:

How can I get my firework objects to have random colors like my confetti objects?

I'm making an eCard with falling confetti and fireworks flying up from the bottom of the screen. The logic for both are almost identical:

I make an empty array for fireworks and confetti, and then fill them with objects, using my GetRandom(mix,max) function to create each one with a random value:

//fill confetti object array
for (i = 0; i < NUM_CONFETTI; i++) {
    ConfettiArray.push(new Confetti(GetRandom(0,canvas.width), GetRandom(-200,-10), GetRandom(10,30), GetRandom(10,30), colorChoices[GetRandom(0,NUM_COLORS)], GetRandom(0,2*Math.PI),GetRandom(50,80)));
}
//fill firework object array
for (i = 0; i < NUM_FIREWORKS; i++) {
    FireworkArray.push(new Firework(GetRandom(0,canvas.width), canvas.height, GetRandom(4,20), colorChoices[GetRandom(0,NUM_COLORS)], GetRandom(30,100), GetRandom(-10,10), GetRandom(50,200)));
}

Then they are drawn and updated in their specific ways, each one starting by setting context.fillStyle and .strokeStyle as the current object's color value:

//confetti.draw
Draw: function(x, y, width, height, color, rotationAngle) {
        context.translate(x,y)
        context.rotate(rotationAngle)
        context.strokeStyle = color;
        context.fillStyle = color;
        context.beginPath();
        context.rect(0, 0, width, height);
        context.fill();
        context.closePath();
        context.resetTransform();
    }, 
//firework.draw
Draw: function(x, y, lineWidth, color, speedY, swayX, blastRadius) {
        context.fillStyle = color;
        context.strokeStyle = color;
        context.moveTo(x,y);
        context.lineTo(x-swayX,y-speedY);
        context.stroke();
    },

Then they are each updated:

//confetti.update
Update: function(modifier) {
        this.y = this.y + (this.fallSpeed * modifier);
        if (this.y > canvas.height) {this.x = GetRandom(0,canvas.width);this.y = GetRandom(-100,0);}
    },
//firework.update
Update: function(modifier) {
        this.x = this.x - this.swayX;
        this.y = this.y - this.speedY;
        if (this.y < -10) {this.x = GetRandom(0,canvas.width);this.y = canvas.height;this.speedY = GetRandom(30,100);this.swayX = GetRandom(-10,10)}
    },

I have scoured the code over and over and I just can't seem to get a reason as to why the confetti all has random sizes, angles, fallrates, and colors, AND the fireworks all have random swayX and speedY values but all the same colors. The full code is below if anyone wants to run it in full:

//james gossling multimedia for web design spring 2018
var canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d');

var GetRandom = function(min, max) {
    //set mins and maxes for ball speed to change angle slightly after ball reset
    min = min;
    max = max;
    return Math.floor(Math.random() * (max - min + 1) + min);
};  
//game classes go here
var Background = function(context,color) {
    this.context = context;
    this.color = color;
};
Background.prototype = {

    DrawBackground: function() {
    //for testing
    //console.log('here')
    context.strokeStyle = this.color;
    context.fillStyle = this.color;
    context.beginPath();
    context.rect(0,0,canvas.width,canvas.height);
    context.stroke(); // invoke stroke
    context.fill(); // invoke fill
    context.closePath();
},


};

Confetti = function(x, y, width, height, color, rotationAngle, fallSpeed) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.color = color;
    this.rotationAngle = rotationAngle;
    this.fallSpeed = fallSpeed;
};
Confetti.prototype = {
    Draw: function(x, y, width, height, color, rotationAngle) {
        context.translate(x,y)
        context.rotate(rotationAngle)
        context.strokeStyle = color;
        context.fillStyle = color;
        context.beginPath();
        context.rect(0, 0, width, height);
        context.fill();
        context.closePath();
        context.resetTransform();
    },
    GetX: function() {
        return this.x;
    },
    GetY: function() {
        return this.y;
    },
    GetWidth: function() {
        return this.width;
    },
    GetHeight: function() {
        return this.height;
    },
    GetColor: function() {
        return this.color;
    },
    GetRotationAngle: function() {
        return this.rotationAngle;
    },
    GetFallSpeed: function() {
        return this.fallSpeed;
    },

    Update: function(modifier) {
        this.y = this.y + (this.fallSpeed * modifier);
        if (this.y > canvas.height) {this.x = GetRandom(0,canvas.width);this.y = GetRandom(-100,0);}
    },

};
var DrawConfetti = function() {
    for (i = 0; i < NUM_CONFETTI; i++) {
        ConfettiArray[i].Draw(ConfettiArray[i].GetX(),ConfettiArray[i].GetY(),ConfettiArray[i].GetWidth(),ConfettiArray[i].GetHeight(),ConfettiArray[i].GetColor(),ConfettiArray[i].GetRotationAngle());
    }
}
var UpdateConfetti = function(modifier) {
    for (i = 0; i < NUM_CONFETTI; i++) {
        ConfettiArray[i].Update(modifier);
    }
};

Firework = function(x, y, lineWidth, color, speedY, swayX, blastRadius) {
    this.x = x;
    this.y = y;
    this.lineWidth = lineWidth;
    this.color = color;
    this.speedY = speedY;
    this.swayX = swayX;
    //this.rotationAngle = rotationAngle;
    this.blastRadius = blastRadius;
};
Firework.prototype = {
    Draw: function(x, y, lineWidth, color, speedY, swayX, blastRadius) {
        context.fillStyle = color;
        context.strokeStyle = color;
        context.moveTo(x,y);
        context.lineTo(x-swayX,y-speedY);
        context.stroke();
    },
    GetX: function() {
        return this.x;
    },
    GetY: function() {
        return this.y;
    },
    GetLineWidth: function() {
        return this.lineWidth;
    },
    GetColor: function() {
        return this.color;
    },
    GetSpeedY: function() {
        return this.speedY;
    },
    GetSwayX: function() {
        return this.swayX;
    },
    GetRotationAngle: function() {
        return this.rotationAngle;
    },
    GetBlastRadius: function() {
        return this.blastRadius;
    },
    Update: function(modifier) {
        this.x = this.x - this.swayX;
        this.y = this.y - this.speedY;
        if (this.y < -10) {this.x = GetRandom(0,canvas.width);this.y = canvas.height;this.speedY = GetRandom(30,100);this.swayX = GetRandom(-10,10)}
    },
};
var DrawFireworks = function() {
    //create confetti object array
    for (i = 0; i < NUM_FIREWORKS; i++) {
        FireworkArray[i].Draw(FireworkArray[i].GetX(), FireworkArray[i].GetY(), FireworkArray[i].GetLineWidth(), FireworkArray[i].GetColor(), FireworkArray[i].GetSpeedY(),  FireworkArray[i].GetSwayX(), FireworkArray[i].GetBlastRadius());
    }
};
var UpdateFireworks = function(modifier) {
    for (i = 0; i < NUM_FIREWORKS; i++) {
        FireworkArray[i].Update(modifier);
    }
};

UncleSam = function() {

};
UncleSam.prototype = {



};

Text = function(context,title,x,y,color) {
    this.context = context;
    this.title = title;
    this.x = x;
    this.y = y;
    this.color = color;
    this.lineWidth = 2;
    this.lineHeight =(this.context.measureText('W').width) + Math.pow((this.context.measureText('W').width),2);
    this.font = '70pt Times New Roman';
    //GET METRICS
    this.metrics = this.context.measureText(this.title);
    this.width = this.metrics.width;
    this.maxWidth = canvas.width;
    this.GradChangeSpeed = .5;
    this.GradChangeOffset = .3;
    this.debugCounter = 0;
};
Text.prototype = {

    SetAttributes: function() {
        context.font
        context.textAlign = 'center'
        context.font = this.font;
        context.lineWidth = this.lineWidth;
        context.lineHeight = this.GetHeight;
        context.fillStyle = TextGradient;
        context.strokeStyle = this.color;
        //shadow attributes
        context.shadowColor = undefined;
        context.shadowOffsetX = 0;
        context.shadowOffsetY = 0;
        context.shadowBlur = 0;
    },
    //GETTTERS SETTERS///////////////////
    GetTextX: function() {
        return this.x;
    },
    GetTextY: function() {
        return this.y;
    },
    GetTextLineHeight: function() {
        return this.lineHeight;
    },
    GetTextWidth: function() {
        return this.width;
    },
    //GETTERS SETTERS////////////
    SetColorGradient: function() {
        TextGradient.addColorStop(0,"red");
        TextGradient.addColorStop(this.GradChangeOffset,"white");
        TextGradient.addColorStop(.8,"blue");
    },
    Update: function(modifier) {
        this.GradChangeOffset = this.GradChangeOffset + (this.GradChangeSpeed * modifier);
        //GRADIENT DEBUGGERS
        context.strokeText(this.GradChangeOffset.toFixed(2),canvas.width/2,canvas.height/2);
        //GRADIENT DEBUGGERS
        if (this.GradChangeOffset > .7 || this.GradChangeOffset < .2) {this.GradChangeSpeed = -(this.GradChangeSpeed);}
    },

    DrawText: function() {
        this.WrapText(this.context, this.title, this.x, this.y, this.maxWidth, this.lineHeight);
    },

    WrapText: function(context, title, x, y, maxWidth, lineHeight) {

        var words = title.split(' ');
        var line = '';

        for(var n = 0; n < words.length; n++) {
            var testLine = line + words[n] + ' ';
            var metrics = context.measureText(testLine);
            var testWidth = metrics.width;

            if (testWidth > maxWidth && n > 0) {
                context.fillText(line, x, y);
                context.strokeText(line, x, y);
                line = words[n] + ' ';
                y += lineHeight;
            }
            else {
                line = testLine;
            }
        }

        context.fillText(line, x, y);
        context.strokeText(line, x, y);
    },

};

//other functions
var ClearScreen = function() {
    context.clearRect(0, 0, canvas.width, canvas.height);
};

var DrawObjects = function() {
    ClearScreen();
    Background1.DrawBackground();
    Text1.SetAttributes();
    Text1.SetColorGradient();
    Text1.DrawText();
    DrawFireworks();
    DrawConfetti();
};

var UpdateObjects = function(modifier) {
    //Text1.Update(modifier);
    UpdateFireworks(modifier);
    UpdateConfetti(modifier);
};

var Reset = function() {

};
//MAIN GAME LOOP FXN///////////////////
// The main game loop
var main = function() {
    var now = Date.now();
    var delta = now - then;
    var frameRateAdjust = delta/1000;

    DrawObjects(frameRateAdjust);

    UpdateObjects(frameRateAdjust);

    then = now;

    //possibly do RESET

    // Request to do this again ASAP
    requestAnimationFrame(main);
};

// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;

//START ECARD
//create variables
var then = Date.now();
var colorChoices = ["red","white","blue","deeppink","orange","limegreen","darkred"];
var NUM_CONFETTI = 25;
var NUM_FIREWORKS = 10;
var NUM_COLORS = colorChoices.length;
//create arrays for objects
var ConfettiArray = [];
var FireworkArray = [];
//create objects
Background1 = new Background(context,'black');
var Text1 = new Text(context,'Happy 4th of July!',canvas.width/2,canvas.height/10,'red');
var TextGradient = context.createLinearGradient(Text1.GetTextX(),Text1.GetTextY(),Text1.GetTextX()+Text1.GetTextWidth(),Text1.GetTextY()+Text1.GetTextLineHeight()/2)

//fill confetti object array
for (i = 0; i < NUM_CONFETTI; i++) {
    ConfettiArray.push(new Confetti(GetRandom(0,canvas.width), GetRandom(-200,-10), GetRandom(10,30), GetRandom(10,30), colorChoices[GetRandom(0,NUM_COLORS)], GetRandom(0,2*Math.PI),GetRandom(50,80)));
}
//fill firework object array
for (i = 0; i < NUM_FIREWORKS; i++) {
    FireworkArray.push(new Firework(GetRandom(0,canvas.width), canvas.height, GetRandom(4,20), colorChoices[GetRandom(0,NUM_COLORS)], GetRandom(30,100), GetRandom(-10,10), GetRandom(50,200)));
}

//start eCard animations
Reset();
main();

Upvotes: 0

Views: 74

Answers (1)

Blindman67
Blindman67

Reputation: 54099

Begin a new path with ctx.beginPath()

The reason is because you are creating one path out of all the firework lines.

//firework.draw
Draw: function(x, y, lineWidth, color, speedY, swayX, blastRadius) {
    context.fillStyle = color;
    context.strokeStyle = color;  // sets the stroke color
    context.moveTo(x,y);          // adds another line
    context.lineTo(x-swayX,y-speedY);
    context.stroke();             // stroke all lines up to this point
},

Each time stroke is called all the firework lines are render up to that point.

The result is that the last stroke call draws all the lines again the color of the last firework.

The fix

The fix is simple. Just start a new path with ctx.beginPath()

//firework.draw
Draw: function(x, y, lineWidth, color, speedY, swayX, blastRadius) {
    context.fillStyle = color;
    context.strokeStyle = color;  // sets the stroke color

    //========================================================
    context.beginPath();          // start a new path
    //========================================================


    context.moveTo(x,y);          
    context.lineTo(x-swayX,y-speedY);
    context.stroke();             
},

Upvotes: 0

Related Questions