xxxxxxxxxx
86
let glyphs = ["@", "#", "*", "+", ":", ".", " "];
let numPoints = 3000;
let numTurns = 20;
let particles = [];
let windStrength = 0.2; // Stronger push for dramatic motion
let recoveryFactor = 0.002;
let windDirection = 1;
let windTimer = 0;
let fallSpeed = 0; // Simulated gravity effect
let maxFallSpeed = 4; // How fast the spiral falls forward
function setup() {
createCanvas(600, 600);
background(0);
textFont("monospace");
textAlign(CENTER, CENTER);
for (let i = 0; i < numPoints; i++) {
let angle = map(i, 0, numPoints, 0, TWO_PI * numTurns);
let radius = map(i, 0, numPoints, 5, width / 2);
let x = radius * cos(angle) + width / 2;
let y = radius * sin(angle) + height / 2;
let ditherIndex = floor(map(radius, 0, width / 2, 0, glyphs.length));
ditherIndex = constrain(ditherIndex, 0, glyphs.length - 1);
let glyph = glyphs[ditherIndex];
particles.push(new Particle(x, y, glyph, radius, angle));
}
}
function draw() {
background(0, 40);
// Increase fall speed over time, then reverse after reaching peak
fallSpeed += 0.05 * windDirection;
fallSpeed = constrain(fallSpeed, -maxFallSpeed, maxFallSpeed);
// This was meant to actually pull the object back up when dropped, but it didn't work
if (fallSpeed >= maxFallSpeed || fallSpeed <= -maxFallSpeed) {
windDirection *= -1;
}
let windForce = createVector(0, fallSpeed * windStrength);
for (let p of particles) {
p.applyForce(windForce);
p.update();
p.display();
}
}
// Particle class
class Particle {
constructor(x, y, glyph, radius, angle) {
this.originalPos = createVector(x, y);
this.pos = createVector(x, y);
this.vel = createVector(0, 0);
this.acc = createVector(0, 0);
this.glyph = glyph;
this.radius = radius;
this.angle = angle;
}
applyForce(force) {
this.acc.add(force);
}
update() {
this.vel.add(this.acc);
this.pos.add(this.vel);
this.vel.mult(0.98);
this.acc.mult(0);
}
display() {
let depthFactor = map(this.vel.y, -maxFallSpeed, maxFallSpeed, 0.5, 2); // Perspective effect
let size = map(this.radius, 0, width / 2, 12, 4) * depthFactor;
textSize(size);
fill(255);
text(this.glyph, this.pos.x, this.pos.y);
}
}