我目前正在尝试学习JavaScript并正在尝试使用canvas
动画。我尝试使用canvas
创建焰火效果。我使用this source作为参考。
到目前为止,我已经成功创建了一个单一粒子并让它射向天空。但是,我不能让它爆炸...... 我的代码和逻辑有问题吗?我真的很感激,如果有人能够查看我的代码并给我一些建议,我该怎么做才能纠正它。
以下是我的.js
代码:
const canvas = document.getElementById('myCanvas');
const context = canvas.getContext('2d');
let w = canvas.width;
let h = canvas.height;
w = window.innerWidth;
h = window.innerHeight;
let particles = [];
class Particle{
constructor(pos, vel, target){
// firework animation properties
this.gravity = 1;
this.alpha = 1;
this.easing = Math.random() * 0.02;
this.fade = Math.random() * 0.1;
this.pos = {
x: pos.x || 0,
y: pos.y || 0
};
this.vel = {
x: vel.x || 0,
y: vel.y || 0
};
this.target = {
y: target.y || 0
};
this.lastPos = {
x: this.pos.x,
y: this.pos.y
};
}
update(){
this.lastPos.x = this.pos.x;
this.lastPos.y = this.pos.y;
this.vel.y += this.gravity;
this.pos.y += this.vel.y;
this.alpha -= this.fade;
this.distance = (this.target.y - this.pos.y);
// ease the position
this.pos.y += this.distance * (0.03 + this.easing);
// cap to 1
this.alpha = Math.min(this.distance * this.distance * 0.00005, 1);
this.pos.x += this.vel.x;
return (this.alpha < 0.005);
}
draw(){
let x = Math.round(this.pos.x),
y = Math.round(this.pos.y),
xVel = (x - this.lastPos.x) * -5,
yVel = (y - this.lastPos.y) * -5;
context.fillStyle = "rgba(255,255,255,0.3)";
context.beginPath();
context.moveTo(this.pos.x, this.pos.y);
context.lineTo(this.pos.x + 1.5, this.pos.y);
context.lineTo(this.pos.x + xVel, this.pos.y + yVel);
context.lineTo(this.pos.x - 1.5, this.pos.y);
context.closePath();
context.fill();
}
}
const init = () =>{
// set canvas size to window size
onResize();
document.addEventListener('mouseup', createParticle, true);
// set off fireworks
update();
}
const update = () =>{
// clear up the canvas
clearCanvas();
// start the animation loop
requestAnimFrame(update);
createFireworks();
}
const createFireworks = () =>{
for(let i = 0; i < particles.length; i++){
if(particles[i].update()){
// kill off the firework, replace it
// with the particles for the exploded version
particles.splice(particles.length, 1);
explodeFireworks(particles[i]);
}
particles[i].draw();
}
console.log(particles.length);
}
const explodeFireworks = (firework) =>{
let count = 100;
let angle = (Math.PI * 2) / count;
for(let i = 0; i < count; i++){
let randomVelocity = 4 + Math.random() * 4;
let particleAngle = count * angle;
createParticle(
firework.pos,
{
x: Math.cos(particleAngle) * randomVelocity,
y: Math.sin(particleAngle) * randomVelocity
},
null
);
}
}
//without parameters create particle, with parameters create firework
const createParticle = (pos, vel, target) =>{
pos = pos || {};
vel = vel || {};
target = target || {};
particles.push(
new Particle(
{
x: w/2,
y: h
},
{
x: vel.x || Math.random() * 3 - 1.5,
y: vel.y || 0
},
{
y: target.y || h/2
}
)
);
}
const clearCanvas = () =>{
context.clearRect(0,0,canvas.width, canvas.height);
}
const onResize =() => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
// Simple polyfill for browsers that don't support requestAnimationFrame
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
window.addEventListener('load', init, false);