Creative Coding: Transience
Published 14 April 2025 • 8 min read
Creative coding explores the intersection between art and code. I find it challenging to devote much time to this interest, but I wanted to see how easy it would be to revive something I made many years ago using p5.js and embed it here in a post.
I've enjoyed watching many videos by Daniel Schiffman from The Coding Train over the years, which inspired me to experiment using p5.js.
Created on 15 October 2017 by Joseph Hosier
Creating an Interactive Particle System with p5.js
Have you ever wanted to build your own particle system from scratch—complete with decaying trails, drag, and dynamic acceleration? Well, dust off your sliders, because that's exactly what this p5.js sketch does. In this post, we’ll step through the code and show how each part works, using snippets and explanations to make it all clear.
1. Global Variables and Tuning Knobs
We begin by declaring our essential variables:
var system;
var acc_Slider;
var acc_coefficient = 0.01;
var init_v_max = 5;
var lifespan = 550;
var drag_coefficient = 10 / 100000;
system
: our particle manager.acc_Slider
: a slider to dynamically tweak particle acceleration.acc_coefficient
: this is what the slider controls.- Other constants define speed, drag, and how long each particle lives.
2. Setting up the Canvas and Slider
We create a canvas and attach a slider for real-time acceleration control:
function setup() {
const parentWidth = document.getElementById('sketch-holder').offsetWidth;
const canvas = createCanvas(parentWidth, parentWidth * 0.5);
canvas.parent('sketch-holder');
acc_Slider = createSlider(0, 0.1, 0.01, 0.001);
acc_Slider.parent('slider-holder');
system = new ParticleSystem();
clear();
}
- The canvas scales with the container (but only checks the size when the page is reloaded).
- The slider appears below the canvas and ranges from 0 to 0.1.
- A
ParticleSystem
instance is born. We'll dive into that shortly.
3. Main Loop – draw()
In each frame, we:
- Read the slider value.
- Clear the screen.
- Spawn 8 new particles.
- Run the system.
function draw() {
acc_coefficient = acc_Slider.value();
clear();
for (let i = 0; i < 8; i++) {
system.addParticle();
}
system.run();
}
This keeps the sketch alive, responsive, and delightfully chaotic.
4. Particle Lifecycle: Born, Live, Die
Each Particle
is an object and has its own internal logic that handles the laws of physics. A partical has a state consisting of four parameters: life, position, acceleration and velocity. When a Particle
instance is created, it is assigned a remaining life of lifespan
, a random velocity (in the x-y plane) and 0 acceleration.
var Particle = function(position) {
this.acceleration = createVector(0, 0);
this.velocity = createVector(random(-init_v_max, 0), random(-init_v_max / 10, init_v_max / 10));
this.position = position.copy();
this.life = lifespan;
};
In update()
we define how acceleration evolves:
Particle.prototype.update = function() {
if (this.life / lifespan > 0.66) {
this.acceleration = createVector(-0.05, 0); // Birth
} else if (this.life / lifespan > 0.33) {
this.acceleration = createVector(acc_coefficient * (width / 2 - this.position.x), 0); // Life
} else {
this.acceleration = createVector(-0.5, 0); // Death
}
this.velocity.add(this.acceleration);
this.drag = p5.Vector.mult(this.velocity, -drag_coefficient * (lifespan - this.life));
this.velocity.add(this.drag);
this.position.add(this.velocity);
this.life -= 2;
};
And the visual:
Particle.prototype.display = function() {
stroke(256, 256);
strokeWeight(0);
fill((lifespan - this.life) * 256 / lifespan, 0, this.life * 256 / lifespan, 256);
ellipse(this.position.x, this.position.y, 3, 3);
};
Particles fade as they die, their color shifting from blue to red as their life
parameter reduces towards 0.
5. Managing the Swarm
The ParticleSystem
class spawns and cleans up:
var ParticleSystem = function() {
this.particles = [];
};
ParticleSystem.prototype.addParticle = function() {
this.particles.push(new Particle(createVector(width, random(0, height))));
};
ParticleSystem.prototype.run = function() {
for (var i = this.particles.length - 1; i >= 0; i--) {
var p = this.particles[i];
p.run();
if (p.isDead()) {
this.particles.splice(i, 1);
}
}
};
No ghosts, no clutter—just ephemeral motion.
Conclusion
This project is a dance of code and control: particles come to life, react to your hand via the slider, then vanish into the ether. Whether you’re new to p5.js or refining your generative art toolkit, this sketch invites you to tweak, tinker, and transform it into something your own.
If you're interested in making your version interactive, visual, or even musical—consider hooking up more sliders or audio input. The sky isn’t the limit—your imagination is.