Ollin

Clipping

clipping as drawing state: withClip(shape) { } confines fills, strokes, images, and text to the filled region of the shape, and nested clips intersect

Run
swift run --package-path Examples Example-Shapes-Clipping
Source
Examples/Shapes/Clipping/Sketch.swift
import Ollin

/// Clipping as drawing state: `withClip(shape) { }` confines everything drawn
/// inside the block (fills, strokes, images, text) to the shape's filled
/// region, and nested clips intersect. A field of drifting diagonal stripes
/// exists only inside a slowly turning star-shaped window; a circular lens
/// sweeps across it revealing a second palette where the two regions overlap;
/// and an orbiting dot crosses the boundary untouched, because it draws after
/// the block ends.
@main
final class Clipping: Sketch {
    override func draw() {
        background(Color(hex: 0x101418))
        let center = center

        // The window: a seven-pointed star, slowly turning.
        var star: [Vector2] = []
        for k in 0 ..< 14 {
            let radius = k % 2 == 0 ? 400.0 : 205.0
            let a = Double(k) / 14 * .tau + time * 0.05 - .pi / 2
            star.append(center + Vector2(cos(a) * radius, sin(a) * radius))
        }
        let window = Shape(star)

        // Cool stripes drift through the star; nothing lands outside it.
        withClip(window) {
            noStroke()
            translate(center)
            rotate(0.6)
            let bandWidth = 46.0
            let drift = fract(time * 0.15) * bandWidth * 2
            for i in -16 ... 16 {
                fill(i % 2 == 0 ? Color(hex: 0x2EC4B6) : Color(hex: 0x175E57))
                drawRect(Double(i) * bandWidth + drift, -height, bandWidth, height * 2)
            }
        }

        // A lens orbits the canvas; inside it, a warm palette shows only where
        // lens and star overlap (nested clips intersect).
        let lens = Circle(center: center + Vector2(cos(time * 0.6) * 260,
                                                   sin(time * 0.8) * 190),
                          radius: 190)
        withClip(window) {
            withClip(lens) {
                noStroke()
                translate(center)
                rotate(-0.6)
                let bandWidth = 46.0
                let drift = fract(time * 0.25) * bandWidth * 2
                for i in -16 ... 16 {
                    fill(i % 2 == 0 ? Color(hex: 0xFFD166) : Color(hex: 0xF6511D))
                    drawRect(Double(i) * bandWidth + drift, -height, bandWidth, height * 2)
                }
            }
        }

        // Outside the blocks, drawing is unclipped: the lens outline and an
        // orbiting dot cross the star's boundary freely.
        noFill()
        stroke(Color(hex: 0x9BF6FF).withAlpha(0.5))
        strokeWeight(2)
        drawCircle(center: lens.center, radius: lens.radius)
        let dot = center + Vector2(angle: time * 0.9) * 330
        fill(.white)
        noStroke()
        drawCircle(dot.x, dot.y, 14)

        drawCaption("withClip(shape) confines drawing to a region · nesting intersects · after the block, drawing is free")
    }
}

↑↓ move ↩ open