patternjavascriptMajor
Celebratory fireworks animation
Viewed 0 times
fireworkscelebratoryanimation
Problem
To celebrate an important event, I hastily cobbled together an HTML canvas-based animation.
A few concerns I have include:
While we normally don't say "thanks" on Stack Exchange questions, I'd like to break that rule right now and say a big Thank you! to all members of the Code Review community.
`function animate(selector) {
var $canvas = $(selector);
var width = $canvas.innerWidth();
var height = $canvas.innerHeight();
/ Based on https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSL /
/ hue ∈ [0, 2π), saturation ∈ [0, 1], lightness ∈ [0, 1] /
var fromHSL = function fromHSL(hue, saturation, lightness) {
var c = (1 - Math.abs(2 lightness - 1)) saturation;
var h = 3 * hue / Math.PI;
var x = c * (1 - (h % 2 - 1));
var r1 = (h = 0; f--) {
var particles = objects[f].particles;
for (var p = particles.length - 1; p >= 0; p--) {
var particle = particles[p];
context.beginPath();
context.arc(particle.x, particle.y, particle.size, 0, 2 * Math.PI, false);
context.fillStyle = particle.color;
context.fill();
}
objects[f].update();
}
};
var launch = function launch() {
objects.push(factory());
while (objects.length > 4) {
objects.shift();
}
};
this.redrawInterval = setInterval(redraw, 25 / ms /);
this.factoryInterval = setInterval(launch, 1500 / ms /);
}
Animation.prototype.stop = function stop() {
clearInterval(this.redrawInterval);
clearInterval(this.factoryInterval);
}
A few concerns I have include:
- Performance: Does it run reasonably smoothly on most modern machines? How can I make it more efficient?
- Portability / Compatibility: Does it work correctly on all modern browsers (excluding old versions of Internet Explorer)?
- Modelling: Is this a good way to simulate fireworks? Is there anything I could do to enhance the realism?
While we normally don't say "thanks" on Stack Exchange questions, I'd like to break that rule right now and say a big Thank you! to all members of the Code Review community.
`function animate(selector) {
var $canvas = $(selector);
var width = $canvas.innerWidth();
var height = $canvas.innerHeight();
/ Based on https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSL /
/ hue ∈ [0, 2π), saturation ∈ [0, 1], lightness ∈ [0, 1] /
var fromHSL = function fromHSL(hue, saturation, lightness) {
var c = (1 - Math.abs(2 lightness - 1)) saturation;
var h = 3 * hue / Math.PI;
var x = c * (1 - (h % 2 - 1));
var r1 = (h = 0; f--) {
var particles = objects[f].particles;
for (var p = particles.length - 1; p >= 0; p--) {
var particle = particles[p];
context.beginPath();
context.arc(particle.x, particle.y, particle.size, 0, 2 * Math.PI, false);
context.fillStyle = particle.color;
context.fill();
}
objects[f].update();
}
};
var launch = function launch() {
objects.push(factory());
while (objects.length > 4) {
objects.shift();
}
};
this.redrawInterval = setInterval(redraw, 25 / ms /);
this.factoryInterval = setInterval(launch, 1500 / ms /);
}
Animation.prototype.stop = function stop() {
clearInterval(this.redrawInterval);
clearInterval(this.factoryInterval);
}
Solution
Performance
It works fine for me in Opera and Chrome, but it is buggy in Firefox.
Profiling reveals that
But this isn't enough to make it run lag-free in Firefox for me. It works fine with max 3 fireworks and 300 particles (although a bit boring).
Realism
There are a lot of things that could be done to make it more realistic (with a lot of work, and probably heavy performance costs), but I think that your version is quite good. It doesn't actually look that much like real firework, but it's a great representation. It looks good and everybody knows that it's supposed to be fireworks.
The main difference to real fireworks is that the particles of real fireworks don't look like dots most of the time, but like lines (or drops, especially when falling down).
Also, real fireworks tend to come in groups of explosions, not in timed intervals (because it's more exciting to see one giant scene instead of a steady stream of small once). This is not something I would aim for in an animation though.
Naming
Misc
It works fine for me in Opera and Chrome, but it is buggy in Firefox.
Profiling reveals that
redraw is responsible (big surprise :) ), and there is not much to optimize without changing the whole concept. Two minor optimizations might be:- save 2 * Math.PI in a constant.
- assign
context.fillStyle = particle.color;outside the particles loop (all particles of one object have the same color).
But this isn't enough to make it run lag-free in Firefox for me. It works fine with max 3 fireworks and 300 particles (although a bit boring).
Realism
There are a lot of things that could be done to make it more realistic (with a lot of work, and probably heavy performance costs), but I think that your version is quite good. It doesn't actually look that much like real firework, but it's a great representation. It looks good and everybody knows that it's supposed to be fireworks.
The main difference to real fireworks is that the particles of real fireworks don't look like dots most of the time, but like lines (or drops, especially when falling down).
Also, real fireworks tend to come in groups of explosions, not in timed intervals (because it's more exciting to see one giant scene instead of a steady stream of small once). This is not something I would aim for in an animation though.
Naming
objectsis a bit generic, I think.drawableObjectswould be a bit clearer, but as it expects fireworks anyways, I would go withfireworks.
launchalso might be a bit generic.launchFireworkswould make it clear that it adds a new firework (as opposed to say launch the animation, or launch a new particle).
- I would use
fireworksinstead off(and maybeparticleinstead ofp) inredraw.
Misc
- it's fine to hardcode math factors, but if you put the other magic numbers in fields (interval length, number of particles, number of fireworks, time of whole animation, etc), it would be easier to test/change configurations.
Context
StackExchange Code Review Q#64176, answer score: 43
Revisions (0)
No revisions yet.