The Originality Trap
About This Sketch
A visualization of creative synthesis. Three influence sources (circles) remain constant, connected by subtle lines. Synthesis particles periodically emerge from their center, each taking a unique direction—representing how originality comes not from avoiding influence, but from deeply metabolizing multiple sources until something genuinely new emerges.
Algorithm
This sketch visualizes the concept of creative synthesis from multiple influences. Three static "influence" circles represent different sources of inspiration or existing work. These are connected by faint lines, showing relationships between existing ideas.
Periodically, new "synthesis particles" emerge from the centroid (center point) of all influences. Each particle inherits aspects from all influences (blended color, central starting position) but moves in its own unique direction, representing how true originality emerges not from avoiding influence but from metabolizing multiple influences into something new.
The particles fade as they move away from their sources, visualizing how synthesized ideas take on their own life and become distinct from their origins. The visual metaphor: originality isn't created in isolation—it emerges from the unique combination and transformation of existing influences.
Pseudocode
SETUP:
Initialize canvas (400x300)
Create 3 influence circles at fixed positions
Each influence has a position, color hue, and size
DRAW (every frame):
Get current theme colors
Draw semi-transparent background (creates trail effect)
Display all influence circles
Every 15 frames:
Create new synthesis particle
Position at centroid of all influences
Assign random direction and speed
Blend colors from multiple influences
For each synthesis particle:
Move in assigned direction
Fade out over time
Remove when fully faded or off-screen
Draw connecting lines between influences (subtle)
Source Code
let sketch = function(p) {
let influences = [];
let synthesis = [];
let time = 0;
class Influence {
constructor(x, y, hue) {
this.x = x;
this.y = y;
this.hue = hue;
this.size = p.random(20, 40);
this.alpha = 180;
}
display(colors) {
p.noStroke();
let col = p.lerpColor(
p.color(...colors.accent1, this.alpha),
p.color(...colors.accent2, this.alpha),
this.hue
);
p.fill(col);
p.ellipse(this.x, this.y, this.size);
}
}
class SynthesisParticle {
constructor(influences, colors) {
// Start at centroid of influences
let avgX = influences.reduce((sum, inf) => sum + inf.x, 0) / influences.length;
let avgY = influences.reduce((sum, inf) => sum + inf.y, 0) / influences.length;
this.x = avgX;
this.y = avgY;
// Move in unique direction (the "synthesis")
this.angle = p.random(p.TWO_PI);
this.speed = p.random(1, 3);
this.life = 255;
this.size = p.random(4, 8);
// Color blends all influences
this.color = p.lerpColor(
p.color(...colors.accent1),
p.color(...colors.accent3),
p.random()
);
}
update() {
this.x += p.cos(this.angle) * this.speed;
this.y += p.sin(this.angle) * this.speed;
this.life -= 2;
}
display() {
p.noStroke();
this.color.setAlpha(this.life);
p.fill(this.color);
p.ellipse(this.x, this.y, this.size);
}
isDead() {
return this.life <= 0 || this.x < 0 || this.x > 400 || this.y < 0 || this.y > 300;
}
}
p.setup = function() {
p.createCanvas(400, 300);
p.colorMode(p.RGB);
// Create initial influences at fixed positions
influences.push(new Influence(100, 150, 0.2));
influences.push(new Influence(300, 150, 0.5));
influences.push(new Influence(200, 80, 0.8));
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg, 25); // Slight trail effect
// Display influences (constant sources)
for (let inf of influences) {
inf.display(colors);
}
// Generate synthesis particles periodically
time++;
if (time % 15 === 0) {
synthesis.push(new SynthesisParticle(influences, colors));
}
// Update and display synthesis
for (let i = synthesis.length - 1; i >= 0; i--) {
synthesis[i].update();
synthesis[i].display();
if (synthesis[i].isDead()) {
synthesis.splice(i, 1);
}
}
// Draw subtle lines showing influence connections
p.stroke(...colors.accent3, 30);
p.strokeWeight(1);
for (let i = 0; i < influences.length; i++) {
for (let j = i + 1; j < influences.length; j++) {
p.line(influences[i].x, influences[i].y, influences[j].x, influences[j].y);
}
}
};
};