Week 07: Fireworks Project with Ruby | Jonathon Haley

Link to Fireworks

For this project, Ruby and I decided to make a fireworks simulator. Click anywhere on the screen, and fireworks will shoot up and explode. When the fireworks explodes, not only do you see vivid colors and glittering trails, but you also hear one of the fireworks sound samples that we created.

Ruby was in charge of creating and downloading the various sounds we used to create our fireworks sounds. She recorded a number of strange things, such as hitting a whiteboard and crumpling paper bags. Since there were some sounds, such as large explosions, that we could not replicate ourselves, as well as various other noises we decided to include (listen to the sounds closely…), Ruby (and to a lesser extent, myself) also found some sounds online at freesound.org which would serve our purposes.

We combined the recorded and downloaded sounds in Audacity, using a combination of trimming, amplification (volume adjustments for individual tracks), and reverb, to create four very different-sounding fireworks samples.

I was in charge of creating the code and scripts for the fireworks website. My initial idea was to have a black screen (like the night sky at real fireworks shows), and when you click an area on the screen, a GIF of a real fireworks will play where you clicked, and at the same time one of our recorded sound samples will play. However, after some Google searching I found a better solution. I found some Javascript code online at https://codepen.io/whqet/pen/Auzch which served our exact needs – creating fireworks on the screen whenever/wherever the mouse is clicked. I added this code to our script.js file. There’s a line I made in the code using comment /// slashes – everything above it is script and functions that I wrote, and everything below it (besides calls to the above functions, and also tweaks to a few numbers) is from the above link. Per the original script writer’s implementation, I also added a <canvas> element into our index.html page, as well as a bit of CSS for the mouse crosshair style.

A big challenge I faced here was making audio play in the background – not only would a random audio sample (from among the four we recorded) have to play every time a firework is created by the user, but it would also need to be at the same panning (x-axis position) as the place the user clicked. After a bunch of messing and trying different approaches, with help from IMA fellow Tristan, I found the solution to be to create an AudioContext object and StereoPannerNode, and connect the two together. Ruby and I also decided to add a progress bar, which increments every time the user launches a firework. When the progress bar is filled, a bunch of fireworks launch to random parts of the screen and explode, triggering a bunch of different audio samples at once. To make this work, I had to partition much of my code into smaller functions, which could be called multiple times for each firework.

Side note to the user: every time you fill up the progress bar, the fireworks becomes slightly thicker – with more particles exploding out of it. It’s not super noticeable (which is why we don’t point it out on the page), but if you fill it up enough times the fireworks become quite large.

The final problem I dealt with (although it came up pretty early in the process) was making the sound play in Chrome – although the visuals worked fine, you wouldn’t hear anything. This, I learned, was due to restrictions on autoplaying audio set in Chrome, as well as restrictions on running audio locally (possibly also having to do with autoplay restrictions). To circumvent the first issue, I made the audio only load after the first time a user clicks somewhere on the screen, as Chrome allows you to play audio after some sort of user interaction. With IMA fellow Dave’s help, I set up a local host (localhost:8000), and was able to run the website there with no problems. This was a perfect workaround, as it simulated how the website would run after being uploaded to the NAS server, and allowed the audio to play as desired.

In the end, the audio (and the rest of the website) works in both Firefox and Chrome (Firefox didn’t even require running a local host!), but not in Safari. In Safari, when I try to instantiate a new AudioContext with the line “let context = new AudioContext();”, I get the error “Can’t find variable: AudioContext”. Apparently the AudioContext class isn’t accessible in Safari, so as a result the audio for the website doesn’t work in Safari (though the visuals work fine). I’m not sure what the reasons or workarounds for this might be, but it’s not super surprising as different browsers do seem to treat audio a bit differently (hence how Chrome required a local host to play audio, but Firefox didn’t).

In conclusion, while our project may have been simple in concept, it actually took a great deal of work to imagine, create, and execute the various details – especially recording, finding, and combining different sounds to create the fireworks samples, and creating full audio functionality with panning, multiple simultaneous audio tracks, and cross-browser compatibility. I consider this project a success, and look forward to the next one.

Leave a Reply