JavaScript: CSS Animated Fireworks
The following animation is powered entirely by CSS styles using a combination of CSS transforms and keyframes. JavaScript is only being used to generate some of the CSS code and insert randomness, but not to power the animation itself in any way.
The whole script (HTML + CSS + JavaScript) weighs in at around 5 kilobytes. There are no graphics apart from the starry sky background.
Let the Show Begin
If you have a supported browser the animation will start automatically in the field below and run indefinitely. Moving your mouse over the field will pause the animation. The colour and placement of the 'launchers' and 'explosions' is randomised each time you reload the page.
The code as written will work in WebKit (Safari, Chrome and iPhone/iPad) and Mozilla (Firefox) browsers. It should be fairly simple to add support for Opera as well, and possibly Internet Explorer 10.
Cross-browser Complications
While working out how to implement the animation in WebKit was tricky enough, adding support for Mozilla browsers, which should be a simple task, led to some serious hair-tearing.
None of which was helped by the fact that the only error message returned in all cases is:
Error: SYNTAX_ERR: DOM Exception 12
The main problems have to do with how the different browsers handle manipulation of the document.styleSheets object to dynamically add new styles to the page. The normal process is to just append these styles to the first style sheet associated with the page (document.styleSheets[0]) using its insertRule() method.
Unfortunately Firefox has a bizarre restriction that you can only append styles to style sheets hosted at the same domain. God forbid you should virtually try to deface a temporary virtual object. Add to that the fact that we have a varying number of style sheets according to whether ModPagespeed is applied and you see the problem.
The second issue arose when trying to dynamically add -moz- definitions (specifically the @-moz-keyframes definition) to the CSS in WebKit throws an error. As does trying to add @-webkit-keyframes in Firefox.
One way around this is to do some browser detection and pass only the relevant vendor-prefixes (WebKit, Mozilla, Opera or Microsoft are the main ones). The other option, which we've used, is to wrap the relevant lines in a try... catch statement to allow the script to continue.
You can see the hacks we came up with in the JavaScript file below.
Animation Mechanics
The animation uses two keyframes - one for the trajectory of the 'rockets' and another for the shards of light in the explosion. Here you can see a basic sketch of what's going on:
Each rocket is assigned a random starting position along the line at the bottom of the field. It is also assigned a random target within the area marked. As a rocket approaches its target point, it shrinks down to become invisible (0x0 pixels).
At this point the flares are made visible. These are actually a series of DIVs pointing outward in a radial fashion, with a color at the outward tip - like matchsticks. To simulate the explosion they simply increase in length which moves the lights outward.
Because the flares are children of the rockets, they follow the same trajectory downward. The final change is for them to fade away as they drift towards the 'ground'.
JavaScript is used to:
- add all the required elements to the page (DOM);
- create and assign keyframes for each rocket; and
- assign colours and rotate each flare to the right position.
Everything else is done using CSS, and the whole animation could be set up using CSS if we didn't want it to be random each time, but where's the fun in that?
Download Code
Here you can see the complete HTML code for this example, including links to download the CSS and JavaScript code required run the fireworks animation:
<html>
<head>
<title>CSS Animated Fireworks | The Art of Web</title>
<link rel="stylesheet" type="text/css" href="/css-fireworks.css">
</head>
<body>
<div id="stage"><!-- the action happens here --></div>
<script type="text/javascript" src="/css-fireworks.js"></script>
</body>
</html>
Ideally we would get rid of the static CSS file and include all those styles also in the JavaScript - with browser detection to serve only the required vendor prefix for each browser (see link under References below). Even the starting HTML element could be inserted dynamically.
If you have any problems or comments, please let us know using the Feedback form below.
References
Related Articles - Transforms and Transitions
- CSS Transition Timing Functions
- CSS Animation Using CSS Transforms
- CSS Bouncing Ball Animation
- CSS 3D Transforms and Animations
- CSS Upgraded fading slideshow
- CSS Animated Background Gradients
- CSS An actual 3D bar chart
- CSS Infinite Animated Photo Wheel
- CSS Photo Rotator with 3D Effects
- JavaScript CSS Animated Fireworks
- JavaScript Animating objects over a curved path
- CSS Fading slideshow with a touch of JavaScript
- JavaScript Controlling CSS Animations
James Iliff 31 December, 2011
So, Ive been trying to figure out how to set up a hover situation like this,
hover on a div to effect a different div (but not the one being hovered on).
Any thoughts?
I've set up a CSS example you can see here. For more complex examples the solution is to use JavaScript to assign a new className to the target element or elements.