如何让我的烟花对象具有像我的五彩纸屑对象一样的随机颜色?

时间:2018-02-16 05:09:21

标签: javascript html5 oop object canvas

我正在制作一张电子贺卡,其中五彩纸屑和烟花从屏幕底部飞起来。两者的逻辑几乎相同:

我为烟花和五彩纸屑制作一个空数组,然后用对象填充它们,使用我的GetRandom(混合,最大)函数创建每个具有随机值的数据:

//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)));
}

然后以特定方式绘制和更新它们,每个方法首先将context.fillStyle和.strokeStyle设置为当前对象的颜色值:

//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();
    },

然后他们每个都更新:

//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)}
    },

我一遍又一遍地搜索代码,我似乎无法理解为什么五彩纸屑都有随机大小,角度,堕落和颜色,而且烟花都有随机的swayX和speedY值但是所有相同的颜色。如果有人想要完整运行它,那么完整的代码如下:

//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();

1 个答案:

答案 0 :(得分:0)

使用ctx.beginPath()

开始新路径

原因是因为你要从所有烟花线中创建一条路径。

//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
},

每次调用笔划时,所有烟花线都会渲染到该点。

结果是最后一个笔划调用再次绘制了最后一个烟花的颜色。

修复

修复很简单。只需使用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();             
},