SWWheel — Class Reference

SketchWaveJS — SWWheel Saga

A wagon-wheel graphic class composed of SWDisk and SWLine components

Overview

SWWheel is a composite graphic class that renders an animated wagon-wheel on a p5.js canvas. It is built entirely from existing SketchWaveJS components — no raw p5 drawing calls appear in SWWheel itself. The class supports continuous rotation, sinusoidal radius oscillation (“breathing”), and full independent color control for its three visual parts.

SWWheel ├── hub → SWDisk (filled center disk — drawn on top) ├── rim → SWDisk (outlined ring at outer radius, stroke only) └── spokes → SWLine[] (n evenly-spaced lines, center → rim edge) Draw order: rim → spokes → hub
Coordinate system: The center point and all radii are in user/grid units. Stroke weights (rimThickness, spokeThickness) are always in screen pixels. Use drawOnGrid(grid) for the normal canvas workflow; use draw() only when working directly in raw pixel coordinates.

Dependencies

All five must be loaded in your HTML before swWheel.js:

Class / LibraryFileRole in SWWheel
p5.js CDN Canvas, rendering engine — strokeWeight(), line(), etc.
SWColor shapeClasses/swColor.js HSB color objects for hub fill, rim stroke, and spoke stroke
SWPoint shapeClasses/swPoint.js Center point and computed spoke endpoints
SWLine shapeClasses/swLine.js Each individual spoke
SWDisk shapeClasses/swDisk.js Hub (filled) and rim (outlined)
SWGrid shapeClasses/swGrid.js Required only for drawOnGrid()

Constructor

const wheel = new SWWheel({ /* options object — all optional */ });

All options are passed as a single destructured object. Every key has a sensible default, so new SWWheel() with no arguments is valid and produces an 8-spoke wheel centered at the grid origin.

OptionTypeDefaultDescription
center SWPoint SWPoint(0, 0) Wheel center in user/grid coordinates
outerRadius number 80 Rim radius in user units. Also seeds originalOuterRadius.
hubRadius number 10 Hub disk radius in user units
numSpokes number 8 Number of evenly-distributed spokes
rimThickness number 3 Rim stroke weight in pixels. 0 = invisible rim.
spokeThickness number 2 Spoke stroke weight in pixels
hubFillColor SWColor undefined Hub fill. undefined lets p5 use its current fill state.
rimColor SWColor undefined Rim stroke and hub border color (shared)
spokeColor SWColor undefined Spoke stroke color. Each spoke receives its own defensive copy.
Defensive copying: All three color options (and their corresponding setters) apply copy-on-intake. Mutating a SWColor object after passing it to the constructor will not silently change the wheel’s appearance. See the chatlog Turn 10 for a full explanation of the aliasing footgun this prevents.

Public Properties

All constructor options become readable instance properties. For most of them, prefer the setter methods over direct assignment — setters keep the internal SWDisk and SWLine components synchronized.

PropertyTypeNotes
centerSWPointWheel center (user/grid coordinates)
outerRadiusnumberNominal rim radius; updated by setOuterRadius()
originalOuterRadiusnumberBaseline radius; reset() restores currentRadius to this value
hubRadiusnumberHub disk radius (user units)
numSpokesnumberCurrent spoke count
rimThicknessnumberRim stroke weight in pixels (0 = hidden)
spokeThicknessnumberSpoke stroke weight in pixels
hubFillColorSWColorOwned copy of the hub fill color
rimColorSWColorOwned copy of the rim stroke + hub border color
spokeColorSWColorOwned copy of the spoke color template
rotationAnglenumberCurrent accumulated rotation in degrees; set by rotate()
currentRadiusnumberLive rim radius. Equals outerRadius when breathe() is not active.
hubSWDiskHub component (read-only intent)
rimSWDiskRim component (read-only intent)
spokesSWLine[]Spoke array (read-only intent)

Methods

Drawing

SignatureReturnsNotes
draw() void Draws in raw screen/pixel coordinates. Use only when not working with a grid.
drawOnGrid(grid) void Preferred. Draws in user/grid coordinates via the given SWGrid. Draw order: rim → spokes → hub.

Animation

SignatureParametersNotes
rotate(degPerSec, t) degPerSec: number
t: number (s)
Sets rotationAngle = degPerSec × t and repositions all spokes. Positive = CCW in user space (CW on screen, due to Y-axis inversion). Call every frame.
breathe(sinusoid, t) sinusoid: SWSinusoid
t: number (s)
Sets currentRadius from sinusoid.getValue(t), updates the rim disk, and repositions spokes. Call every frame.
reset() Restores rotationAngle to 0 and currentRadius to originalOuterRadius. Call when the user resets the sketch.

Setters

Every setter keeps the internal SWDisk and SWLine components in sync automatically. All color setters apply copy-on-intake.
MethodParameterNotes
setNumSpokes(n) n: number Clamped to ≥ 1. Rebuilds the entire spokes array.
setOuterRadius(r) r: number Updates outerRadius, originalOuterRadius, currentRadius, rim disk radius, and spoke positions.
setHubRadius(r) r: number Updates the hub SWDisk radius.
setSpokeThickness(w) w: number (px) Calls spoke.setThickness(w) on every SWLine in the array.
setRimThickness(w) w: number (px) Pass 0 to hide the rim entirely (guarded in draw/drawOnGrid).
setSpokeColor(swColor) swColor: SWColor Each spoke receives its own copy. Pass undefined to clear color.
setRimColor(swColor) swColor: SWColor Sets rim stroke and hub border color together (shared visual role).
setHubFillColor(swColor) swColor: SWColor Sets the hub disk fill color.

Utility

MethodReturnsExample
toString() string SWWheel(center:(0,0), outerRadius:120, hubRadius:10, numSpokes:10)

Private Methods (internal — do not call directly)

MethodWhen called
_buildComponents() Constructor only. Creates hub, rim, and initial spokes.
_buildSpokes() Constructor and setNumSpokes(). Rebuilds the full spokes array.
_repositionSpokes() Every call to rotate(), breathe(), reset(), and radius/count setters. Updates ptA/ptB of each existing spoke — faster than a full rebuild.

Usage Examples

Minimal wheel at the grid origin

// All defaults — 8 spokes, outerRadius 80, no colors set let wheel, grid; function setup() { createCanvas(400, 400); colorMode(HSB, 360, 100, 100, 100); grid = new SWGrid( /* your grid params */ ); wheel = new SWWheel(); } function draw() { background(0, 0, 90); wheel.drawOnGrid(grid); }

Custom wheel with color and rotation

let wheel, grid, tElapsed = 0; function setup() { createCanvas(500, 500); colorMode(HSB, 360, 100, 100, 100); grid = new SWGrid( /* your grid params */ ); wheel = new SWWheel({ outerRadius: 120, numSpokes: 10, rimThickness: 8, spokeThickness: 8, rimColor: new SWColor(210, 80, 100), // blue spokeColor: new SWColor(210, 80, 100), hubFillColor: new SWColor( 45, 90, 92), // gold }); } function draw() { tElapsed += min(deltaTime / 1000, 0.1); // seconds, capped at 100 ms background(0, 0, 90); wheel.rotate(45, tElapsed); // 45 °/sec CCW (user space) wheel.drawOnGrid(grid); }

Breathing wheel (oscillating radius)

let wave, tElapsed = 0; function setup() { // ... wave = new SWSinusoid({ midValue: 100, // center radius in user units amplitude: 30, // ± 30 units period: 3, // 3-second cycle }); } function draw() { tElapsed += min(deltaTime / 1000, 0.1); wheel.rotate(60, tElapsed); wheel.breathe(wave, tElapsed); // rim and spoke tips pulse together wheel.drawOnGrid(grid); }

Invisible rim — the plus-sign configuration

// rimThickness:0 hides the rim; hubRadius:0 hides the hub. // Result is a clean ✚ shape — the basis for SWCross (Stage 2). const plus = new SWWheel({ numSpokes: 4, rimThickness: 0, hubRadius: 0, spokeThickness: 2, spokeColor: new SWColor(270, 40, 75), });

Wiring UI sliders to setters

// Call once in setup() after the wheel is created. function wireWheelControls() { document.getElementById('numSpokesSlider') .addEventListener('input', e => wheel.setNumSpokes(+e.target.value)); document.getElementById('rimThickSlider') .addEventListener('input', e => wheel.setRimThickness(+e.target.value)); document.getElementById('rimColorPicker') .addEventListener('input', e => { wheel.setRimColor(hexToSWColor(e.target.value)); // your hex helper }); }

Source — shapeClasses/swWheel.js

Loaded live from the file so this view always reflects the current version. Use the button to copy the full source to the clipboard.

Loading source…