RepelGrid
a grid of dots that move away from the cursor (mouseX/mouseY)
- Run
swift run --package-path Examples Example-Input-RepelGrid- Source
- Examples/Input/RepelGrid/Sketch.swift
// Ported from the p5.js sketch week-4/pattern-3 (MIT) in
// https://github.com/eaviles/rtp-sfpc-f21-p5 — itself a p5 port of Zach
// Lieberman's openFrameworks sample for the RTP class at SFPC, Fall 2021
// (https://github.com/ofZach/RTP_SFPC_F21). Reworked for Ollin's API.
import Ollin
/// A 30×30 grid of dots that flee the cursor: each dot is pushed away from
/// `mouseX`/`mouseY` and swells as the pointer nears it.
///
/// `dist` gives each dot's distance to the cursor; `map(..., clamped: true)`
/// turns that into a 0...1 closeness `pct` (1 right under the cursor, 0 once
/// it's 200 points away). `pct` then drives both the push (along the unit
/// vector away from the cursor) and the radius.
@main
final class RepelGrid: Sketch {
override func setup() {
noStroke()
}
override func draw() {
background(.black)
// Canvas-relative so the grid fills any canvas size and the cursor lines
// up with it: a 1/16 inset, a quarter-canvas cursor reach, and a push and
// dot radius scaled to that inset.
let s = shortSide
let margin = s * 0.0625
let reach = s * 0.25
let push = s * 0.0625
let g = grid(columns: 30, rows: 30, padding: .all(margin), distribution: .spanning)
for dot in g.points {
let x = dot.position.x, y = dot.position.y
let distance = dist(x, y, mouseX, mouseY)
let pct = map(distance, 0, reach, 1, 0, clamped: true)
var dx = x - mouseX
var dy = y - mouseY
if distance > 0 { // normalize to a unit push direction
dx /= distance
dy /= distance
}
drawCircle(x + dx * pct * push,
y + dy * pct * push,
margin * (0.1 + 0.16 * pct))
}
}
}