Intro
One of the things I love the most about the HTML5 canvas are particle systems. For this post I prepared a small but good looking example. One of the colleagues from work even thought that I used some kind of graphical framework to do this and couldn't believe it's just plain old javascript.
The Particle definition
var Particle = function (ind) {
// remember the index inside array
// faster performance on collisions
this.ind = ind;
// initial position
this.x = randomMax(canvas.width);
this.y = randomMax(canvas.height);
// random direction vectors
this.dy = -5 + randomMax(10);
this.dx = -5 + randomMax(10);
// radius (small flash in the beginning)
this.r = randomMax(radiusmax);
// give it a random color from the set
this.color = colorSet[Math.floor(Math.random() * colorSet.length)];
};
Particle draw method
// reduce the size of the particle down to the minimal size
// using log function - looks nicer and more organic
this.r = this.r > miParticleSize ?
flashfactor * (Math.log(this.r) / Math.LN10)
: miParticleSize;
// adjust particle position
this.y += this.dy;
this.x += this.dx;
// check for collision with other particles
// only on same color
for (var i = this.ind + 1; i < particleSystem.particles.length; i++) {
if (distance(this, particleSystem.particles[i]) < criticalDistance
&& this.color === particleSystem.particles[i].color) {
this.r = radiusmax;
particleSystem.particles[i].r = radiusmax;
}
}
// if the particle is outside of the canvas
// or moving vectors are both 0
if (this.x < 0 || this.x > canvas.width
|| this.y < 0 || this.y > canvas.height
|| (this.dy === 0 && this.dx === 0)) {
// initialize the particle again
this.x = randomMax(canvas.width);
this.y = randomMax(canvas.height);
this.dy = -5 + randomMax(10);
this.dx = -5 + randomMax(10);
}
ctx.beginPath();
// this is the part that makes people thing it's a framework
// simple radial gradient
fillStyle = ctx.createRadialGradient(this.x, this.y, this.r * 0.001,
this.x, this.y, this.r
);
fillStyle.addColorStop(0, this.color);
fillStyle.addColorStop(1, particleBackground);
// particle drawing code
ctx.fillStyle = fillStyle;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.fill();
Other than helper function and standard shims that's all there is to it.
Firefox issues
I couldn't find why firefox deals so bad with a larger number of particles, essentially everything freezes past 100 particles on firefox. Initialy I thought it's my draw method, but turned out that there's not much to be improved there.
Even when I removed the draw code and let the firefox "draw" the objects with an empty method the performace was still very poor (around 5-6 fps). If you perhaps figured it out or know about some issues please let me know!
And here's my example on:Codepen
No comments:
Post a Comment