Spaces:
Running
Running
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); | |
} | |
}`; |