ArrayList<Particle> particles = new ArrayList<Particle>();
boolean drawAsPoints = false;
ArrayList<String> words = new ArrayList<String>();
color bgColor = color(255, 100);
String fontName = "Arial Bold";
PVector pos = new PVector(0, 0);
PVector vel = new PVector(0, 0);
PVector acc = new PVector(0, 0);
PVector target = new PVector(0, 0);
float closeEnoughTarget = 50;
boolean isKilled = false;
color startColor = color(0);
color targetColor = color(0);
float colorBlendRate = 0.025;
float proximityMult = 1.0;
float distance = dist(this.pos.x, this.pos.y, this.target.x, this.target.y);
if (distance < this.closeEnoughTarget) {
proximityMult = distance/this.closeEnoughTarget;
PVector towardsTarget = new PVector(this.target.x, this.target.y);
towardsTarget.sub(this.pos);
towardsTarget.normalize();
towardsTarget.mult(this.maxSpeed*proximityMult);
PVector steer = new PVector(towardsTarget.x, towardsTarget.y);
steer.mult(this.maxForce);
color currentColor = lerpColor(this.startColor, this.targetColor, this.colorWeight);
point(this.pos.x, this.pos.y);
ellipse(this.pos.x, this.pos.y, this.particleSize, this.particleSize);
if (this.colorWeight < 1.0) {
this.colorWeight = min(this.colorWeight+this.colorBlendRate, 1.0);
PVector randomPos = generateRandomPos(width/2, height/2, (width+height)/2);
this.target.x = randomPos.x;
this.target.y = randomPos.y;
this.startColor = lerpColor(this.startColor, this.targetColor, this.colorWeight);
this.targetColor = color(0);
PVector generateRandomPos(int x, int y, float mag) {
PVector randomDir = new PVector(random(0, width), random(0, height));
PVector pos = new PVector(x, y);
void nextWord(String word) {
PGraphics pg = createGraphics(width, height);
PFont font = createFont(fontName, 100);
pg.text(word, width/2, height/2);
color newColor = color(random(0.0, 255.0), random(0.0, 255.0), random(0.0, 255.0));
int particleCount = particles.size();
ArrayList<Integer> coordsIndexes = new ArrayList<Integer>();
for (int i = 0; i < (width*height)-1; i+= pixelSteps) {
for (int i = 0; i < coordsIndexes.size (); i++) {
int randomIndex = (int)random(0, coordsIndexes.size());
int coordIndex = coordsIndexes.get(randomIndex);
coordsIndexes.remove(randomIndex);
if (pg.pixels[coordIndex] != 0) {
int x = coordIndex % width;
int y = coordIndex / width;
if (particleIndex < particleCount) {
newParticle = particles.get(particleIndex);
newParticle.isKilled = false;
newParticle = new Particle();
PVector randomPos = generateRandomPos(width/2, height/2, (width+height)/2);
newParticle.pos.x = randomPos.x;
newParticle.pos.y = randomPos.y;
newParticle.maxSpeed = random(2.0, 5.0);
newParticle.maxForce = newParticle.maxSpeed*0.025;
newParticle.particleSize = random(3, 6);
newParticle.colorBlendRate = random(0.0025, 0.03);
particles.add(newParticle);
newParticle.startColor = lerpColor(newParticle.startColor, newParticle.targetColor, newParticle.colorWeight);
newParticle.targetColor = newColor;
newParticle.colorWeight = 0;
newParticle.target.x = x;
newParticle.target.y = y;
if (particleIndex < particleCount) {
for (int i = particleIndex; i < particleCount; i++) {
Particle particle = particles.get(i);
nextWord(words.get(wordIndex));
rect(0, 0, width*2, height*2);
for (int x = particles.size ()-1; x > -1; x--) {
Particle particle = particles.get(x);
if (particle.pos.x < 0 || particle.pos.x > width || particle.pos.y < 0 || particle.pos.y > height) {
particles.remove(particle);
String tipText = "Left-click for a new word.";
tipText += "\nDrag right-click over particles to interact with them.";
tipText += "\nPress any key to toggle draw styles.";
text(tipText, 10, height-40);