Spaces:
Running
Running
export const lightReasoning = "For 'light', I'll create particles that emit a soft glow and pulse rhythmically. The particles will be arranged in a pattern that suggests rays or beams of light, with subtle movement and size variations. The color palette will focus on warm, bright tones, and I'll use the screen blend mode to create authentic light-like effects."; | |
export const lightSketch = `let font; | |
let fontSize = 200; | |
let word = "light"; | |
let points; | |
let particles = []; | |
let lightCycleSpeed = 0.02; | |
let particleMinSize = 5; | |
let particleMaxSize = 5; | |
let shadowBlurAmount = 30; | |
let minX, maxX; | |
let color1 = "#217BFE"; | |
let color2 = "#078BFE"; | |
let color3 = "#AC87EB"; | |
let lightColor; | |
function preload() { | |
font = loadFont('/fonts/GoogleSans-Bold.ttf'); | |
} | |
function setup() { | |
createCanvas(500, 500); | |
background(0); | |
lightColor = color(255, 255, 255); | |
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); | |
} | |
points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, { | |
sampleFactor: 0.1 | |
}); | |
minX = width; | |
maxX = 0; | |
for (let pt of points) { | |
minX = min(minX, pt.x); | |
maxX = max(maxX, pt.x); | |
} | |
for (let i = 0; i < points.length; i++) { | |
let pt = points[i]; | |
particles.push(new Particle(pt.x, pt.y, i)); | |
} | |
} | |
function draw() { | |
blendMode(BLEND); // Reset to default blend mode first | |
background(0); // Clear with black background | |
blendMode(SCREEN); // Then set screen blend mode for particles | |
for (let particle of particles) { | |
particle.update(); | |
particle.display(); | |
} | |
} | |
class Particle { | |
constructor(x, y, index) { | |
this.pos = createVector(x, y); | |
this.size = random(particleMinSize, particleMaxSize); | |
this.alpha = 255; | |
this.lightOffset = index * 0.1; | |
} | |
update() { | |
// No position update needed for light animation | |
} | |
getBaseColor() { | |
let normalizedX = map(this.pos.x, minX, maxX, 0, 1); | |
let baseParticleColor; | |
if (normalizedX < 0.5) { | |
baseParticleColor = lerpColor(color(color1), color(color2), normalizedX * 2); | |
} else { | |
baseParticleColor = lerpColor(color(color2), color(color3), (normalizedX - 0.5) * 2); | |
} | |
return baseParticleColor; | |
} | |
display() { | |
let brightness = sin(frameCount * lightCycleSpeed + this.lightOffset); | |
brightness = map(brightness, -1, 1, 0, 1); | |
brightness = constrain(brightness, 0, 1); | |
let baseParticleColor = this.getBaseColor(); | |
let particleColor = lerpColor(baseParticleColor, lightColor, brightness); | |
noStroke(); | |
if (brightness > 0.8) { | |
drawingContext.shadowBlur = shadowBlurAmount; | |
drawingContext.shadowColor = color(255); | |
fill(particleColor); | |
ellipse(this.pos.x, this.pos.y, this.size * 1.5, this.size * 1.5); | |
drawingContext.shadowBlur = 0; | |
} else { | |
drawingContext.shadowBlur = 0; | |
fill(particleColor); | |
ellipse(this.pos.x, this.pos.y, this.size, this.size); | |
} | |
} | |
}`; |