export const riseReasoning = "For 'rise', I'll create a staged animation where particles gradually appear, pause briefly, then float upward. This creates a sense of emergence and ascension. Each particle follows this sequence independently with slight timing variations, creating a continuous cycle of rising elements. The fade-in adds a gentle, ethereal quality that matches the upward motion."; export const riseSketch = `let font; let fontSize = 200; let word = "rise"; let points; let particles = []; let floatSpeed = 4; let fadeInSpeed = 10; let minWaitTime = 50; let maxWaitTime = 200; let particleMinSize = 3; let particleMaxSize = 7; let color1 = "#217BFE"; let color2 = "#078BFE"; let color3 = "#AC87EB"; function preload() { font = loadFont('/fonts/GoogleSans-Bold.ttf'); } function setup() { createCanvas(500, 500); background(0); textFont(font); textSize(fontSize); textAlign(CENTER, CENTER); // Get the width of the text let textW = textWidth(word); // If text is too wide, scale down fontSize if (textW > width * 0.8) { fontSize = fontSize * (width * 0.8) / textW; textSize(fontSize); textW = textWidth(word); } // Get points for the text centered in canvas points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, { sampleFactor: 0.1 }); // Find min and max x positions for color gradient let minX = points[0].x; let maxX = points[0].x; for (let pt of points) { minX = min(minX, pt.x); maxX = max(maxX, pt.x); } let xRange = maxX - minX; for (let pt of points) { particles.push(new Particle(pt.x, pt.y, pt.x, minX, xRange)); } } function draw() { blendMode(BLEND); background(0); blendMode(SCREEN); for (let particle of particles) { particle.update(); particle.display(); } } class Particle { constructor(x, y, particleX, minX, xRange) { this.pos = createVector(x, y); this.originalPos = createVector(x, y); this.originalX = x; this.originalY = y; this.size = random(particleMinSize, particleMaxSize); this.alpha = 255; this.floatSpeedVariation = random(0.5, 2.0); this.isFadingIn = true; this.isWaiting = false; this.waitTime = 0; this.particleX = particleX; this.minX = minX; this.xRange = xRange; this.color = this.getColorForPosition(); } getColorForPosition() { let normalizedX = 0; if (this.xRange > 0) { normalizedX = constrain((this.particleX - this.minX) / this.xRange, 0, 1); } let particleColor; if (normalizedX < 0.5) { particleColor = lerpColor(color(color1), color(color2), normalizedX * 2); } else { particleColor = lerpColor(color(color2), color(color3), (normalizedX - 0.5) * 2); } return particleColor; } update() { if (this.isFadingIn) { this.alpha += fadeInSpeed; if (this.alpha >= 255) { this.alpha = 255; this.isFadingIn = false; this.isWaiting = true; this.waitTime = floor(random(minWaitTime, maxWaitTime)); } } else if (this.isWaiting) { this.waitTime--; if (this.waitTime <= 0) { this.isWaiting = false; } } else { this.pos.y -= floatSpeed * this.floatSpeedVariation; if (this.pos.y < -this.size) { this.respawn(); } } } respawn() { this.pos.y = this.originalPos.y; this.pos.x = this.originalPos.x; this.alpha = 0; this.isFadingIn = true; this.isWaiting = false; this.waitTime = 0; this.size = random(particleMinSize, particleMaxSize); this.floatSpeedVariation = random(0.5, 2.0); this.color = this.getColorForPosition(); } display() { noStroke(); fill(red(this.color), green(this.color), blue(this.color), this.alpha); ellipse(this.pos.x, this.pos.y, this.size, this.size); } }`;