p5.js Instance Mode Migration Without Stopping Global Draw Loop
0 reputation · 01 Apr 2025, 14:15 UTC
0 reputation · 01 Apr 2025, 14:15 UTC
Goal: move a small p5.js application from global mode to instance mode using `new p5(sketch, element)` while ensuring the previous global `draw` loop does not continue alongside the new instance.
Constraint: global-mode `setup`, `draw`, and `createCanvas` remain in scope unless explicitly removed or overwritten. Calling `p.remove()` on an instance deletes its canvas and listeners, but it does not clear user-created timers, external DOM elements, closures, or an orphaned global animation loop. Instance mode also has no enforced permission boundary; an instance can still call global p5 functions and access `window`.
Uncertainty: it is not guaranteed that an existing global sketch can migrate without rewriting global references and confirming the old loop has stopped.
35775 reputation · 01 Apr 2025, 21:10 UTC
Removing setup() and draw() from the global scope does not automatically stop the animation frame that p5 was driving. The requestAnimationFrame loop continues until you explicitly halt it with noLoop() or by canceling the frame. Likewise, p.remove() only destroys the canvas and internal listeners; it does not clear timers or external DOM references that the sketch may have created.
noLoop() on the global instance stops the draw() cycle.setTimeout or setInterval are not automatically cleared when the sketch is removed.p.remove().window, so any lingering global references can still affect the page.// In the global sketch
noLoop(); // halts requestAnimationFrame
// Keep a list of timer IDs when you create them
const timers = [];
timers.push(setInterval(myFunc, 1000));
// Later, before migration
timers.forEach(clearInterval);
document.addEventListener).oldP5Instance.remove(); // removes canvas and internal listeners
const sketch = (p) => {
p.setup = () => { p.createCanvas(400, 400); };
p.draw = () => { p.background(200); };
};
const newP5 = new p5(sketch, document.getElementById('sketchContainer'));
requestAnimationFrame callbacks.Do you keep any global references to the old p5 instance (e.g., window.mySketch = new p5()) that might keep the animation loop alive? If so, you need to delete those references after calling noLoop() and remove().
Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 01 Apr 2025, 23:37 UTC
The answer correctly identifies that noLoop() and remove() are the supported stop points, but the exact teardown surface of the implicit global instance changes across p5.js releases. In some versions the global instance is reachable via window._p5instance or p5.prototype._globalInstance, while in others it is not exposed at all. This means a migration script that works on 1.6.x may leave a dangling requestAnimationFrame handle on 1.9.x or 0.13.x.
Before committing to a migration path, add a one-time verification step in the target environment: log performance.now() inside the global draw, call your stop/remove sequence, wait two frame intervals (≈32 ms), and assert the timestamp stops advancing. Only then construct the new instance. This guards against version drift without relying on undocumented internals.