Click to Launch Fireworks - xelsed.ai

This sketch creates an interactive nighttime fireworks display: clicking anywhere on the canvas launches a glowing rocket that rises, explodes into 50-100 colorful particles, and fades away under gravity. It uses HSB color mode for vibrant hues, p5.Vector math for realistic motion, and a fading background trick to leave glowing trails.

🧪 Try This!

Experiment with the code by making these changes:

  1. Make gravity much stronger — Particles will fall back down noticeably faster after each explosion, making bursts feel heavier and shorter-lived.
  2. Leave much longer glowing trails — Lowering the background alpha makes old frames fade out more slowly, leaving long streaky trails behind every point.
  3. Supersize the explosions — Increasing the particle count per burst turns each firework into a much denser, more dramatic shower of sparks.
Prefer the full editor? Open it there →

📖 About This Sketch

Clicking anywhere on this canvas launches a rocket from the bottom of the screen toward your cursor; when it arrives it bursts into a shower of 50 to 100 glowing particles that arc outward, fall under gravity, and slowly fade into the night sky. The sketch leans heavily on p5.Vector for position, velocity, and acceleration, HSB colorMode for effortlessly vibrant random hues, and a semi-transparent background() call to create smooth motion trails instead of harsh flicker. Two ES6 classes - Firework and Particle - keep the physics for the rocket and its explosion neatly organized.

The code is organized around a small array of active Firework objects that setup() and draw() manage every frame, while mousePressed() adds a new firework on demand and windowResized() keeps the canvas full-screen. Studying it will teach you how to model projectile motion with vectors, how object-oriented classes make a particle system manageable, and how alpha blending on the background can fake glowing trails cheaply.

⚙️ How It Works

  1. When the sketch loads, setup() creates a full-window canvas, paints it black, defines a downward gravity vector, sets the stroke weight, and switches to HSB color mode so random hues always look vibrant.
  2. Every frame, draw() paints a mostly-transparent black rectangle over everything (creating fading trails instead of a hard wipe), then loops backwards through the fireworks array calling update() and show() on each one, removing any firework whose done() method reports it has fully faded.
  3. Clicking the mouse triggers mousePressed(), which pushes a brand new Firework aimed at the click position into the array - the rocket starts at a random x position along the bottom edge.
  4. Inside Firework.update(), while the rocket hasn't exploded it moves under its own velocity toward the target; once it's within 10 pixels of the target, explode() spawns 50-100 Particle objects at that point, each shooting outward in a random direction.
  5. Each Particle.update() call adds the shared global gravity vector to its acceleration, updates velocity and position, and decreases its lifespan value, which is used both to know when the particle is 'done' and to fade its alpha in show().
  6. windowResized() keeps the canvas matching the browser size whenever the window changes, so the display always fills the screen.

🎓 Concepts You'll Learn

p5.Vector physicsHSB color modeES6 classesObject-oriented particle systemsAlpha transparency for trailsArray management with spliceGravity simulationMouse interaction

📝 Code Breakdown

setup()

setup() runs once when the sketch starts. It's the right place to configure the canvas, color mode, and any constant vectors like gravity that will be reused every frame.

function setup() {
  // Create a canvas that fills the entire browser window
  createCanvas(windowWidth, windowHeight);
  // Set the background to black for a night sky effect
  background(0);
  
  // Initialize gravity vector (downwards)
  gravity = createVector(0, 0.2); // Adjust 0.2 for stronger/weaker gravity
  
  // Set stroke weight for drawing points
  strokeWeight(4);
  
  // Set color mode to HSB for easier generation of bright, random colors
  // Hue: 0-255 (full color spectrum)
  // Saturation: 0-255 (0=grayscale, 255=vibrant)
  // Brightness: 0-255 (0=black, 255=white)
  // Alpha: 0-255 (0=transparent, 255=opaque)
  colorMode(HSB, 255);
}
Line-by-line explanation (5 lines)
createCanvas(windowWidth, windowHeight);
Creates a canvas that exactly matches the browser window's current width and height, so the fireworks fill the whole screen.
background(0);
Paints the canvas solid black once at startup to set the night-sky scene before any drawing happens.
gravity = createVector(0, 0.2); // Adjust 0.2 for stronger/weaker gravity
Creates a p5.Vector pointing straight down with a small magnitude - this single vector is added to every particle's acceleration each frame to simulate gravity.
strokeWeight(4);
Sets the default line/point thickness to 4 pixels, used for drawing the rising rocket's bright point.
colorMode(HSB, 255);
Switches p5's color system from default RGB to Hue-Saturation-Brightness with a 0-255 range, making it trivial to generate random vivid colors by just randomizing hue while keeping saturation and brightness maxed out.

draw()

draw() is p5's animation loop, running about 60 times per second. Managing an array of live objects here - updating, showing, then conditionally removing them - is the standard pattern for any particle system or game with multiple active entities.

🔬 This loop updates every active firework once per frame. What happens visually if you call firework.update() twice in a row here - do the rockets and particles move faster?

  for (let i = fireworks.length - 1; i >= 0; i--) {
    let firework = fireworks[i];
    
    // Update the firework's position and state
    firework.update();
function draw() {
  // Redraw background with slight transparency to create firework trails
  background(0, 25); // 25 alpha value makes it fade slowly
  
  // Loop through all fireworks from the end to the beginning
  // This allows safe removal of fireworks from the array during iteration
  for (let i = fireworks.length - 1; i >= 0; i--) {
    let firework = fireworks[i];
    
    // Update the firework's position and state
    firework.update();
    // Display the firework (or its particles if exploded)
    firework.show();
    
    // If the firework (or all its particles) has faded out, remove it
    if (firework.done()) {
      fireworks.splice(i, 1);
    }
  }
}
Line-by-line explanation (5 lines)

🔧 Subcomponents:

for-loop Reverse Fireworks Loop for (let i = fireworks.length - 1; i >= 0; i--) {

Iterates backwards through the fireworks array so items can be safely removed with splice() mid-loop without skipping the next element.

conditional Cleanup Check if (firework.done()) {

Removes a firework from the array once it (and all its exploded particles) has completely faded, keeping the array from growing forever.

background(0, 25); // 25 alpha value makes it fade slowly
Instead of fully clearing the canvas, this draws a mostly-transparent black rectangle over everything - old pixels only partially fade each frame, which is what creates the glowing streaks behind moving points.
for (let i = fireworks.length - 1; i >= 0; i--) {
Loops through the array from the last index down to 0. Going backwards means removing an item with splice() doesn't shift the indices of items you still need to visit.
firework.update();
Calls the Firework's own update method, which moves the rocket or updates all its particles depending on whether it has exploded yet.
firework.show();
Draws the current state of the firework - either a single bright rising point, or all of its exploded particles.
if (firework.done()) { fireworks.splice(i, 1); }
Checks if the firework has exploded and every one of its particles has faded out; if so, removes it from the array so it's no longer processed or drawn.

mousePressed()

mousePressed() is a p5.js event function that automatically runs whenever the mouse button is clicked - it's the standard way to hook up user interaction without writing your own event listeners.

function mousePressed() {
  // Create a new firework at the current mouse position
  // The firework will start from the bottom and travel to this target
  fireworks.push(new Firework(mouseX, mouseY));
}
Line-by-line explanation (1 lines)
fireworks.push(new Firework(mouseX, mouseY));
Creates a brand new Firework object aimed at wherever the mouse was clicked (mouseX, mouseY) and adds it to the fireworks array so draw() will start updating and showing it.

windowResized()

windowResized() is another automatic p5.js event function, called whenever the browser viewport changes size. Pairing it with windowWidth/windowHeight keeps full-screen sketches responsive.

function windowResized() {
  // Resize the canvas to match the new window dimensions
  resizeCanvas(windowWidth, windowHeight);
}
Line-by-line explanation (1 lines)
resizeCanvas(windowWidth, windowHeight);
Whenever the browser window changes size, this resizes the canvas element to match the new width and height so the fireworks display always fills the screen.

Firework constructor()

Constructors run once when a new object is created with 'new'. Here it sets up all the vectors and flags a Firework needs to travel toward its target - a great example of using vector subtraction to aim one object at another.

constructor(targetX, targetY) {
    // Starting position at the bottom of the canvas, random X
    this.pos = createVector(random(width), height);
    // Target position (where the mouse was clicked)
    this.target = createVector(targetX, targetY);
    // Velocity vector calculated to reach the target from the starting position
    this.vel = p5.Vector.sub(this.target, this.pos);
    // Set the magnitude (speed) of the firework's ascent
    this.vel.setMag(random(8, 12)); // Adjust 8, 12 for different firework speeds
    
    // Acceleration vector (initially 0, gravity will be applied to particles)
    this.acc = createVector(0, 0);
    
    // Flag to check if the firework has exploded
    this.exploded = false;
    // Array to hold particles after explosion
    this.particles = [];
    
    // Random hue for this firework and its particles
    this.hu = random(255);
  }
Line-by-line explanation (7 lines)
this.pos = createVector(random(width), height);
Places the rocket's starting position at a random x along the very bottom edge of the canvas (y = height).
this.target = createVector(targetX, targetY);
Stores the click position as the point this rocket is aiming for.
this.vel = p5.Vector.sub(this.target, this.pos);
Subtracting the starting position from the target gives a vector pointing directly from the rocket toward its destination - this becomes the initial velocity direction.
this.vel.setMag(random(8, 12)); // Adjust 8, 12 for different firework speeds
setMag() keeps the direction of the vector but resets its length (speed) to a random value between 8 and 12, so every rocket travels at a slightly different pace.
this.acc = createVector(0, 0);
Starts acceleration at zero; while ascending, no forces act on the rocket itself (gravity only applies after it explodes into particles).
this.exploded = false;
A flag that tracks whether this firework has already burst - used to decide whether to update/draw it as a rocket or as a cloud of particles.
this.hu = random(255);
Picks one random hue (0-255 in HSB mode) that will be shared by the rocket and all of its resulting particles, so each explosion is a single consistent color.

Firework.done()

done() is a helper method that lets draw() decide when it's safe to remove an object from the array. Keeping this logic inside the class (rather than in draw()) keeps the code organized and reusable.

done() {
    // If exploded, check if all particles are done
    if (this.exploded) {
      return this.particles.length === 0;
    } else {
      // If not exploded, it's not done yet
      return false;
    }
  }
Line-by-line explanation (3 lines)

🔧 Subcomponents:

conditional Exploded State Check if (this.exploded) {

Only considers the firework 'done' after it has exploded AND every one of its particles has faded away.

if (this.exploded) {
Checks whether this firework has already burst into particles.
return this.particles.length === 0;
If it has exploded, it's only truly finished once its particles array is empty (every particle has faded and been removed).
return false;
If it hasn't exploded yet, it's definitely not done - the rocket is still rising.

Firework.update()

This method shows a state machine pattern in a single object: it behaves completely differently depending on this.exploded, letting one class represent two visual phases (rising rocket, then particle explosion) without needing two separate classes.

🔬 This checks the distance to the target every frame. What happens if you change 10 to 100 - do fireworks start exploding noticeably earlier, before they visually reach your click?

      let d = p5.Vector.dist(this.pos, this.target);
      
      // If the firework is close enough to its target, explode
      if (d < 10) { // Adjust 10 for explosion threshold
        this.explode();
        this.exploded = true;
      }
update() {
    if (!this.exploded) {
      // Apply acceleration (currently 0 for firework's ascent, gravity affects particles)
      this.vel.add(this.acc);
      // Move the firework
      this.pos.add(this.vel);
      // Reset acceleration for next frame
      this.acc.mult(0);
      
      // Calculate distance to target
      let d = p5.Vector.dist(this.pos, this.target);
      
      // If the firework is close enough to its target, explode
      if (d < 10) { // Adjust 10 for explosion threshold
        this.explode();
        this.exploded = true;
      }
    } else {
      // If exploded, update each particle
      for (let i = this.particles.length - 1; i >= 0; i--) {
        let particle = this.particles[i];
        particle.update();
        // Remove particles that have faded out
        if (particle.done()) {
          this.particles.splice(i, 1);
        }
      }
    }
  }
Line-by-line explanation (10 lines)

🔧 Subcomponents:

conditional Pre-Explosion Movement if (!this.exploded) {

While the rocket hasn't exploded, moves it toward its target and checks how close it has gotten.

conditional Explosion Trigger if (d < 10) { // Adjust 10 for explosion threshold

Triggers the explosion once the rocket is within 10 pixels of its target destination.

for-loop Particle Update Loop for (let i = this.particles.length - 1; i >= 0; i--) {

Updates every particle from this explosion and removes any that have fully faded, iterating backwards for safe removal.

if (!this.exploded) {
Branches behavior: rockets that haven't exploded yet move toward their target; exploded ones instead manage their particle cloud.
this.vel.add(this.acc);
Adds the current acceleration to velocity - currently acc is zero for the rocket, so velocity stays constant during ascent.
this.pos.add(this.vel);
Moves the rocket forward by adding its velocity vector to its position - this is the core of vector-based motion.
this.acc.mult(0);
Resets acceleration to zero so forces don't accumulate incorrectly between frames.
let d = p5.Vector.dist(this.pos, this.target);
Calculates the straight-line distance between the rocket's current position and its target using p5's built-in vector distance function.
if (d < 10) { // Adjust 10 for explosion threshold
Once the rocket gets within 10 pixels of the target, it's considered 'arrived' and should explode.
this.explode(); this.exploded = true;
Calls explode() to generate the burst of particles, then flips the exploded flag so future frames treat this object as a particle cloud instead of a rocket.
for (let i = this.particles.length - 1; i >= 0; i--) {
Loops backwards through this firework's particles so any that are removed with splice() don't disrupt the iteration.
particle.update();
Applies gravity, moves, and fades each individual particle.
if (particle.done()) { this.particles.splice(i, 1); }
Removes a particle from the array once its lifespan has run out, keeping the particles array from growing forever.

Firework.show()

show() is kept separate from update() so that drawing logic and physics logic don't get tangled together - a common and useful convention in creative coding classes.

show() {
    if (!this.exploded) {
      // Before explosion, draw the firework as a bright point
      stroke(this.hu, 255, 255); // Full saturation and brightness
      point(this.pos.x, this.pos.y);
    } else {
      // After explosion, draw each particle
      for (let particle of this.particles) {
        particle.show();
      }
    }
  }
Line-by-line explanation (3 lines)

🔧 Subcomponents:

conditional Rocket vs Particles Drawing if (!this.exploded) {

Draws either a single bright rocket point, or every particle in the explosion, depending on state.

for-loop Particle Drawing Loop for (let particle of this.particles) {

Calls show() on every particle belonging to this explosion so they all get drawn each frame.

stroke(this.hu, 255, 255); // Full saturation and brightness
Sets the drawing color using this firework's random hue with maximum saturation and brightness, since colorMode(HSB) is active - this makes the rocket glow vividly.
point(this.pos.x, this.pos.y);
Draws a single point at the rocket's current position, using the current strokeWeight and stroke color.
for (let particle of this.particles) { particle.show(); }
Uses a for...of loop to call show() on every particle in this firework's explosion, drawing the whole burst.

Firework.explode()

explode() demonstrates how one object can spawn many child objects at once - the core idea behind virtually every particle system, from fireworks to fire, smoke, and rain effects.

🔬 This loop decides how many particles appear in each burst. What happens if you change random(50, 100) to a fixed number like 300 - does the explosion feel denser but slower to compute?

    for (let i = 0; i < random(50, 100); i++) {
      // Create a new particle at the explosion position with the firework's hue
      this.particles.push(new Particle(this.pos.x, this.pos.y, this.hu));
    }
explode() {
    // Generate between 50 and 100 particles
    for (let i = 0; i < random(50, 100); i++) {
      // Create a new particle at the explosion position with the firework's hue
      this.particles.push(new Particle(this.pos.x, this.pos.y, this.hu));
    }
  }
Line-by-line explanation (2 lines)

🔧 Subcomponents:

for-loop Particle Spawn Loop for (let i = 0; i < random(50, 100); i++) {

Creates a random number of particles (between 50 and 100) all at the rocket's current position, giving every explosion a slightly different density.

for (let i = 0; i < random(50, 100); i++) {
Loops a random number of times between 50 and 100 - note random() is called fresh each check, but since it doesn't change the loop condition meaningfully mid-loop in practice, this reliably spawns roughly that many particles.
this.particles.push(new Particle(this.pos.x, this.pos.y, this.hu));
Creates a new Particle at the exact explosion point, passing along the firework's shared hue so all particles from one burst share a color, and adds it to this firework's particles array.

Particle constructor()

p5.Vector.random2D() combined with mult() is a classic technique for radial explosions - pick a random direction, then scale it to a random length, and you get particles scattering realistically in every direction.

constructor(x, y, hu) {
    // Particle's position (explosion point)
    this.pos = createVector(x, y);
    // Random initial velocity, spreading outward
    this.vel = p5.Vector.random2D();
    this.vel.mult(random(1, 8)); // Adjust 1, 8 for different particle spread speeds
    
    // Acceleration vector (gravity will be applied here)
    this.acc = createVector(0, 0);
    
    // Lifespan for fading out (starts fully opaque)
    this.lifespan = 255;
    // Hue inherited from the firework
    this.hu = hu;
  }
Line-by-line explanation (5 lines)
this.pos = createVector(x, y);
Starts every particle at the exact point where the firework exploded.
this.vel = p5.Vector.random2D();
p5.Vector.random2D() returns a unit vector pointing in a completely random direction - this is what makes particles fly outward in every direction from the explosion point.
this.vel.mult(random(1, 8)); // Adjust 1, 8 for different particle spread speeds
Scales that random direction by a random speed between 1 and 8, so particles fly outward at varying speeds, creating a natural-looking burst rather than a perfect ring.
this.lifespan = 255;
Starts the particle fully opaque (255 matches the max alpha in this HSB 0-255 color range) - this value will count down each frame to fade the particle out.
this.hu = hu;
Stores the hue passed in from the parent Firework, so every particle from one explosion shares the same color.

Particle.done()

Keeping this check as its own tiny method makes the calling code (in Firework.update()) read clearly as 'if (particle.done())' rather than repeating the raw comparison everywhere.

done() {
    return this.lifespan < 0;
  }
Line-by-line explanation (1 lines)
return this.lifespan < 0;
Simply reports whether this particle's lifespan has counted down past zero - once true, the particle is fully faded and can be safely removed.

Particle.update()

This is a textbook implementation of Euler integration - repeatedly adding acceleration to velocity, and velocity to position - which is how most simple physics-based animations, from bouncing balls to particle systems, are built.

🔬 This is the exact moment gravity affects a particle. What happens visually if you multiply the gravity vector before adding it, e.g. this.acc.add(p5.Vector.mult(gravity, 3)) - do particles fall much faster?

    // Apply gravity to acceleration
    this.acc.add(gravity);
    // Apply acceleration to velocity
    this.vel.add(this.acc);
update() {
    // Apply gravity to acceleration
    this.acc.add(gravity);
    // Apply acceleration to velocity
    this.vel.add(this.acc);
    // Move the particle
    this.pos.add(this.vel);
    // Reset acceleration for next frame
    this.acc.mult(0);
    
    // Decrease lifespan to fade the particle
    this.lifespan -= 5; // Adjust 5 for faster/slower fade
  }
Line-by-line explanation (5 lines)
this.acc.add(gravity);
Adds the global gravity vector to this particle's acceleration every frame, constantly pulling it downward.
this.vel.add(this.acc);
Applies the accumulated acceleration to velocity - this is what causes the particle's downward speed to keep increasing over time, simulating realistic falling.
this.pos.add(this.vel);
Moves the particle by its current velocity, the same basic vector-motion pattern used everywhere in this sketch.
this.acc.mult(0);
Resets acceleration to zero after it's been applied, so gravity has to be re-added fresh every frame instead of stacking up incorrectly.
this.lifespan -= 5; // Adjust 5 for faster/slower fade
Counts down the particle's lifespan, which controls both when it's considered 'done' and how transparent it appears in show().

Particle.show()

Tying the alpha channel directly to lifespan is a simple, elegant fade-out technique - no separate 'opacity' variable is needed since the same number that tracks remaining life also controls transparency.

show() {
    // Set stroke color with fading alpha
    stroke(this.hu, 255, 255, this.lifespan);
    strokeWeight(2); // Slightly thinner stroke for particles
    point(this.pos.x, this.pos.y);
  }
Line-by-line explanation (3 lines)
stroke(this.hu, 255, 255, this.lifespan);
Sets the drawing color using the particle's hue at full saturation and brightness, but with alpha equal to its current lifespan - as lifespan counts down, the particle visually fades to transparent.
strokeWeight(2); // Slightly thinner stroke for particles
Makes particle points thinner than the rocket's point (which uses the global strokeWeight of 4), so exploded particles look like a fine spray rather than chunky dots.
point(this.pos.x, this.pos.y);
Draws the particle as a single point at its current position, using the color and stroke weight just set.

📦 Key Variables

fireworks array

Holds every active Firework object currently rising or exploding on screen; draw() loops through it each frame to update, show, and clean up entries.

let fireworks = [];
gravity object

A shared p5.Vector pointing downward that every Particle adds to its own acceleration, simulating a constant downward pull on all explosion debris.

gravity = createVector(0, 0.2);

🔧 Potential Improvements (4)

Here are some ways this code could be enhanced:

FEATURE mousePressed()

The sketch only responds to mouse clicks, so it won't launch fireworks on touchscreens (phones/tablets) unless the browser maps touch to mouse events, which isn't guaranteed on all devices.

💡 Add a matching touchStarted() function that also pushes a new Firework using touch coordinates, ensuring reliable mobile support.

BUG Firework.update()

The explosion check 'if (d < 10)' compares distance every frame, but with high random(8,12) speeds a fast-moving rocket can potentially overshoot the target between frames and never get within 10 pixels, so it would keep flying off-screen without ever exploding.

💡 Also trigger the explosion if distance starts increasing (the rocket has passed its target) or clamp the check to 'the rocket is at or past the target y position' as a safety net.

PERFORMANCE explode() and Particle drawing

Each explosion spawns up to 100 individual objects that each call stroke() and point() every frame; with many overlapping fireworks this means hundreds of separate draw calls per frame, which can slow down on weaker devices.

💡 Batch particles by hue and use beginShape(POINTS)/vertex() or draw to an offscreen buffer to reduce the number of individual WebGL/Canvas state changes.

STYLE Throughout Firework and Particle classes

Magic numbers like 255 (max lifespan), 10 (explosion threshold), 5 (fade speed), and 25 (trail alpha) are scattered across multiple methods, making them harder to find and tune consistently.

💡 Extract these into named constants near the top of the file (e.g. const EXPLOSION_THRESHOLD = 10;) so they're easy to locate and adjust in one place.

🔄 Code Flow

Code flow showing setup, draw, mousepressed, windowresized, fireworkconstructor, fireworkdone, fireworkupdate, fireworkshow, fireworkexplode, particleconstructor, particledone, particleupdate, particleshow

💡 Click on function names in the diagram to jump to their code

graph TD start[Start] --> setup[setup] setup --> draw[draw loop] draw --> reversefireworkloop[Reverse Fireworks Loop] reversefireworkloop --> donecheck[Cleanup Check] donecheck --> explodedcheck[Exploded State Check] explodedcheck --> fireworkupdate[fireworkupdate] fireworkupdate --> ascentbranch[Pre-Explosion Movement] ascentbranch -->|not exploded| fireworkshow[fireworkshow] ascentbranch -->|exploded| explosiontrigger[Explosion Trigger] explosiontrigger --> fireworkexplode[fireworkexplode] fireworkexplode --> particle_spawn_loop[Particle Spawn Loop] particle_spawn_loop --> particleconstructor[particleconstructor] particleconstructor --> particleupdate[particleupdate] particleupdate --> particleupdate_loop[Particle Update Loop] particleupdate_loop --> particledone[particledone] particledone --> particleshow[particleshow] particleshow --> particle_draw_loop[Particle Drawing Loop] particle_draw_loop --> draw click setup href "#fn-setup" click draw href "#fn-draw" click reversefireworkloop href "#sub-reverse-firework-loop" click donecheck href "#sub-done-check" click explodedcheck href "#sub-exploded-check" click fireworkupdate href "#fn-fireworkupdate" click ascentbranch href "#sub-ascent-branch" click explosiontrigger href "#sub-explosion-trigger" click fireworkexplode href "#fn-fireworkexplode" click particle_spawn_loop href "#sub-particle-spawn-loop" click particleconstructor href "#fn-particleconstructor" click particleupdate href "#fn-particleupdate" click particleupdate_loop href "#sub-particle-update-loop" click particledone href "#fn-particledone" click particleshow href "#fn-particleshow" click particle_draw_loop href "#sub-particle-draw-loop"

❓ Frequently Asked Questions

What visual effects can I expect from the Click to Launch Fireworks sketch?

This sketch creates a stunning interactive fireworks display, where each firework explodes into colorful particles against a dark night sky, using vibrant hues generated through HSB color mode.

How can I interact with the Click to Launch Fireworks sketch?

Users can simply click anywhere on the canvas to launch a firework that travels to the clicked location and bursts into colorful particles.

What creative coding concepts are demonstrated in this fireworks display sketch?

The sketch showcases concepts such as object-oriented programming with the Firework class, real-time particle effects, and the use of gravity to simulate natural motion.

Preview

Click to Launch Fireworks - xelsed.ai - p5.js creative coding sketch preview
Sketch Preview
Code flow diagram showing the structure of Click to Launch Fireworks - xelsed.ai - Code flow showing setup, draw, mousepressed, windowresized, fireworkconstructor, fireworkdone, fireworkupdate, fireworkshow, fireworkexplode, particleconstructor, particledone, particleupdate, particleshow
Code Flow Diagram