<script language="javascript" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.8/p5.js"></script>     
body {margin:0px; padding:0px; overflow: hidden}
function setup() {
    createCanvas(windowWidth, windowHeight);
    stepLength = 8;
    x = 0;
    y = 0;
    dx = 0;
    dy = -1;
    steps = 0;
    next = 1;
    phase = 0;
    background(20, 80, 130);
}

// SDF for a rectangle centered at `center` with a given `size` (width and height)
function sdf(p, size, center) {
    const diff = p.copy().sub(center);
    // Compute the "distance" from `p` to the boundary of the rectangle
    return Math.max(Math.abs(diff.x) - size.x, Math.abs(diff.y) - size.y);
}

function draw() {
    for (var i = 0; i < 10; i++) {
        drawMain();
    }
}

function drawMain() {
    const hw = width / 2;
    const hh = height / 2;

    const p = createVector(x * stepLength, y * stepLength); // Current position
    const dist = sdf(p, createVector(128, 64), createVector(0, 0)); // Distance from the rectangle centered at origin
    const size = Math.max(0.25, 1 - (128 - Math.abs(dist)) / 128) * 4; // Size of the marker based on the SDF value

    push();
    translate(hw, hh);

    // Coloring the marker based on whether it is inside (white) or outside (black) the rectangle
    if (dist >= 0) {
        fill(0);
    } else {
        fill(255);
    }
    noStroke();

    drawCircleMarker(p, size);
    pop();

    // Update position
    x += dx;
    y += dy;
    steps++;

    // Change direction
    if (steps >= next) {
        changeDirection();
        if (next * stepLength >= height) {
            resetDrawingParameters();
        }
    }
}

function changeDirection() {
    // Adjust movement direction in a spiral pattern
    steps = 0;
    if (dx == 1) {
        dx = 0; dy = 1;
    } else if (dx == -1) {
        dx = 0; dy = -1;
    } else if (dy == 1) {
        dx = -1; dy = 0;
    } else if (dy == -1) {
        dx = 1; dy = 0;
    }

    if (phase == 1) {
        next++;
    }
    phase = (phase + 1) % 2;
}

function resetDrawingParameters() {
    // Reset parameters when drawing reaches the edge
    background(20, 80, 130);
    x = 0; y = 0; dx = 0; dy = -1; steps = 0; next = 1; phase = 0;
}

function drawCircleMarker(p, size) {
    ellipse(p.x, p.y, size * 2, size * 2);
}
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.