Where ideas percolate and thoughts brew

The Transparency Trap

About This Sketch

A visual meditation on how transparency and "working in public" can paradoxically reduce productivity. Two groups of workers: those working in private (left) make steady progress and ship completed work regularly. Those working in public (right) broadcast their process, receive engagement, but ship far less. The sketch illustrates how splitting attention between doing and performing degrades actual output—focus beats performance every time.

Algorithm

This sketch visualizes the productivity paradox of "working in public" versus working in private. On the left side, private workers make steady progress on their work with minimal distraction. They have subtle progress indicators (barely visible) and produce completed works (glowing circles) at a regular pace. Their focus is undivided. On the right side, public workers are constantly broadcasting their process (expanding waves), receiving engagement (distraction particles), and making much slower progress. They have highly visible progress indicators but rarely ship completed works. Their attention is split between doing and performing. The contrast grows over time: private workers accumulate shipped work while public workers accumulate audience engagement but little output. The sketch illustrates how transparency can become a performance that replaces actual productivity.

Pseudocode

SETUP:
  Initialize canvas (400x300)
  Create private workers (left side, fast progress)
  Create public workers (right side, slow progress)

DRAW (every frame):
  Get current theme colors
  Clear background

  Private workers:
    - Update progress (fast rate: 0.3-0.6)
    - When progress reaches 100%, create completed work
    - Display worker with subtle progress indicator
    - Display completed works with glow effect
    - Track total shipped count

  Public workers:
    - Update progress (slow rate: 0.05-0.15)
    - Broadcast waves (transparency performance)
    - Generate distraction particles (engagement)
    - When progress reaches 100% (rarely), count completion
    - Display worker with visible progress ring
    - Display broadcast waves and distractions
    - Track total shipped count

  Display labels and divider
  Show shipped counts for both sides
  Bottom text: "Focus beats performance"

Source Code

let sketch = function(p) {
    let privateWorkers = [];
    let publicWorkers = [];
    let time = 0;

    class PrivateWorker {
        constructor(x, y) {
            this.x = x;
            this.y = y;
            this.progress = 0;
            this.speed = p.random(0.3, 0.6);
            this.output = [];
            this.focused = true;
            this.workPhase = 0;
            this.completedWorks = 0;
        }

        update() {
            // Steady progress - working in private
            this.progress += this.speed;

            // Create output when work completes
            if (this.progress >= 100) {
                this.output.push({
                    x: this.x + p.random(-10, 10),
                    y: this.y - 40,
                    size: 15,
                    alpha: 255,
                    age: 0
                });
                this.completedWorks++;
                this.progress = 0;
            }

            // Update existing output (fading completed works)
            for (let i = this.output.length - 1; i >= 0; i--) {
                this.output[i].age++;
                if (this.output[i].age > 120) {
                    this.output.splice(i, 1);
                }
            }
        }

        display(colors) {
            // Draw completed works
            for (let work of this.output) {
                let fadeAlpha = p.map(work.age, 0, 120, 255, 0);
                p.noStroke();
                p.fill(...colors.accent2, fadeAlpha);
                p.circle(work.x, work.y, work.size);
                // Glow for completed work
                p.fill(...colors.accent2, fadeAlpha * 0.3);
                p.circle(work.x, work.y, work.size * 2);
            }

            // Draw the worker (small, focused)
            p.fill(...colors.accent2, 200);
            p.noStroke();
            p.circle(this.x, this.y, 10);

            // Subtle progress indicator (private - barely visible)
            let progressAngle = p.map(this.progress, 0, 100, 0, p.TWO_PI);
            p.stroke(...colors.accent2, 80);
            p.strokeWeight(1);
            p.noFill();
            p.arc(this.x, this.y, 16, 16, -p.HALF_PI, -p.HALF_PI + progressAngle);
        }
    }

    class PublicWorker {
        constructor(x, y) {
            this.x = x;
            this.y = y;
            this.progress = 0;
            this.speed = p.random(0.05, 0.15); // Much slower - distracted
            this.distractions = [];
            this.broadcastRadius = 0;
            this.completedWorks = 0;
        }

        update() {
            // Slow progress - constantly documenting
            this.progress += this.speed;

            // Broadcast waves (sharing process)
            this.broadcastRadius += 2;
            if (this.broadcastRadius > 60) {
                this.broadcastRadius = 0;
            }

            // Create distraction particles (likes, comments, engagement)
            if (p.random() < 0.05) {
                this.distractions.push({
                    x: this.x + p.random(-40, 40),
                    y: this.y + p.random(-40, 40),
                    life: 100
                });
            }

            // Update distractions
            for (let i = this.distractions.length - 1; i >= 0; i--) {
                this.distractions[i].life--;
                if (this.distractions[i].life <= 0) {
                    this.distractions.splice(i, 1);
                }
            }

            // Rarely actually complete work
            if (this.progress >= 100) {
                this.completedWorks++;
                this.progress = 0;
            }
        }

        display(colors) {
            // Draw broadcast waves (transparency performance)
            p.noFill();
            for (let i = 0; i < 3; i++) {
                let r = (this.broadcastRadius + i * 20) % 60;
                let alpha = p.map(r, 0, 60, 100, 0);
                p.stroke(...colors.accent3, alpha);
                p.strokeWeight(1);
                p.circle(this.x, this.y, r * 2);
            }

            // Draw distraction particles
            p.noStroke();
            for (let d of this.distractions) {
                let alpha = p.map(d.life, 0, 100, 0, 150);
                p.fill(...colors.accent3, alpha);
                p.circle(d.x, d.y, 4);
            }

            // Draw the worker (same size but surrounded by noise)
            p.fill(...colors.accent3, 180);
            p.noStroke();
            p.circle(this.x, this.y, 10);

            // Very visible progress indicator (everything is public)
            let progressAngle = p.map(this.progress, 0, 100, 0, p.TWO_PI);
            p.stroke(...colors.accent3, 150);
            p.strokeWeight(2);
            p.noFill();
            p.arc(this.x, this.y, 25, 25, -p.HALF_PI, -p.HALF_PI + progressAngle);
        }
    }

    p.setup = function() {
        p.createCanvas(400, 300);
        p.colorMode(p.RGB);

        // Create private workers (left side)
        for (let i = 0; i < 2; i++) {
            privateWorkers.push(new PrivateWorker(80, 100 + i * 80));
        }

        // Create public workers (right side)
        for (let i = 0; i < 2; i++) {
            publicWorkers.push(new PublicWorker(320, 100 + i * 80));
        }
    };

    p.draw = function() {
        const colors = getThemeColors();
        p.background(...colors.bg);

        time++;

        // Labels
        p.fill(...colors.accent2, 180);
        p.noStroke();
        p.textAlign(p.CENTER);
        p.textSize(11);
        p.text('Private', 80, 30);

        p.fill(...colors.accent3, 180);
        p.text('Public', 320, 30);

        // Divider
        p.stroke(...colors.accent1, 50);
        p.strokeWeight(1);
        p.line(200, 40, 200, 260);

        // Update and display all workers
        for (let worker of privateWorkers) {
            worker.update();
            worker.display(colors);
        }

        for (let worker of publicWorkers) {
            worker.update();
            worker.display(colors);
        }

        // Count completed works
        let privateCount = privateWorkers.reduce((sum, w) => sum + w.completedWorks, 0);
        let publicCount = publicWorkers.reduce((sum, w) => sum + w.completedWorks, 0);

        // Bottom status
        p.noStroke();
        p.textSize(10);
        p.textAlign(p.LEFT);
        p.fill(...colors.accent2, 150);
        p.text(`Shipped: ${privateCount}`, 20, 280);

        p.textAlign(p.RIGHT);
        p.fill(...colors.accent3, 150);
        p.text(`Shipped: ${publicCount}`, 380, 280);

        // Main message
        p.textAlign(p.CENTER);
        p.textSize(9);
        p.fill(...colors.accent1, 150);
        p.text('Focus beats performance', 200, 270);
    };
};