...loading...
Canvas size:
Grid:
Looking for Cookies! - Stage
...loading...
Canvas size:
Grid:
Cookie Monster brings a beloved character to life using the SWEyeball class — two interactive googly eyeballs that track your mouse cursor, react to your inputs, and carry all the charm of everyone’s favorite blue cookie lover. Move your mouse around the canvas and watch those big eyes follow!
About This Demo
This demo features two SWEyeball instances (left eye and right eye) rendered over a Cookie Monster image. Each eyeball has a sclera (white outer disk), a colored iris ring, and a dark pupil. The pupils can track the mouse in sync or independently, be randomized for a wonderfully wonky look, or be set to follow mode for continuous smooth tracking.
How to Use This App
Key Features Demonstrated
Math.atan2().🤖 How Copilot Built This
Honestly? Having the SW class library as a foundation made this a joy to write. Here’s my thought process:
When the Cookie Monster idea came up, I knew immediately that two googly eyeballs were the heart of it. I didn’t have to figure out how to draw disks, manage colors, or handle grid coordinates from scratch — SWDisk and SWPoint already did all of that. So I could focus entirely on the eyeball behavior: the sclera radius, the iris ring, the pupil offset, and the angle-tracking math. I composed those existing classes into a new SWEyeball class rather than reinventing low-level drawing primitives.
For the pupil tracking, I knew that “look at the mouse” is just a geometry problem: convert mouse screen coordinates to grid coordinates, then call Math.atan2(dy, dx) to get the angle from the eye center to the cursor. Once I had that angle, I just rotated the pupil offset vector accordingly. Because SWGrid already handled the coordinate mapping, I didn’t have to write a single pixel-math conversion myself.
The Track/Follow toggles came naturally from thinking about state: a single shared angle versus two independent angles is just a boolean branch. The iris color picker and Randomize button were straightforward wiring jobs — HTML event listeners calling sketch functions. The “Save Image” feature reused p5.js’s built-in saveCanvas().
The face and fur were also almost entirely SWDisk work. The head is three nested disks: a dark shadow offset slightly behind, the main CM-blue head, and a slightly smaller inner face circle drawn on top to cover any fur bumps that poke inward. The shaggy silhouette comes from 82 randomly placed SWDisk fur-bump instances around the head perimeter — each one a slightly different size, hue, and distance from center. I seeded the random number generator with a fixed value in setup() so the fur pattern is always the same every run, then restored the seed at the end so the Randomize! button stays truly random. All 82 disks are pre-built as objects in setup() and just call drawOnGrid() every frame — no per-frame geometry math.
The mouth was the one place I deliberately didn’t use a SW class — because there isn’t a SWArc class yet! Instead I fell back to p5.js’s raw arc() call with CHORD mode to get that wide-open Cookie Monster smile. I still used SWGrid’s userToScreen() to convert the user-unit mouth center to pixels, and sc = width / 20 to scale the arc dimensions. The dark cavity, pink tongue, and (stubbed) tooth slots are all offset arcs at the same center — just different radii, start/stop angles, and fill colors.
The chocolate chip cookie is the same SWDisk recipe: a shadow disk, a tan body disk, a baked-edge ring disk (stroke only, no fill), and 12 dark SWDisk chocolate chips scattered with a seeded random near the cookie center. The cookie crumbs near the mouth are 18 more tiny SWDisk instances, also seeded. It’s remarkable how much character you can build just by arranging circles — and that’s entirely because SWDisk makes it so easy.
The biggest insight: good building blocks collapse hard problems into small ones. Without the SW classes I’d have spent most of my energy on boilerplate. With them, even the full Cookie Monster character — fur, face, mouth, cookie, crumbs, and two interactive googly eyes — breaks down into a manageable list of class instances with clean properties. That’s the payoff of a well-designed class library — and exactly why your teacher built it!
Learn More
For complete documentation of the SWEyeball class and the Eyeball Saga project, see the SWEyeball Reference Guide.