p5.js is a state machine where fill, stroke, and transform calls persist until overridden, so wrapping elements in push/pop prevents transform accumulation
Every p5.js draw call (fill, stroke, translate, rotate, colorMode) modifies global state that persists for all subsequent draw calls in that frame — and across frames when inside draw(). Without push()/pop() boundaries, a translate() accumulates every frame (causing progressive drift or ever-faster spinning), and fill() bleeds colour onto the next shape. The rule is: wrap every element that has its own transform or style in push(); …; pop(). A translate in draw() without push/pop compounds across frames — a classic performance-breaking bug that appears immediately.
Examples
push(); translate(x,y); rotate(angle); ellipse(0,0,30); pop(); — the transform is isolated. Without push/pop, calling rotate(0.01) in draw() spins the shape faster each frame.
Assessment
Explain why a translate(mouseX, mouseY) placed in draw() without push/pop causes the canvas to drift away from the mouse position over time. Show the fix.