I’m trying to run a p5.js sketch on my Gatsby website, and I’ve managed to get it to work by starting it in instance mode in useEffect
in a component. It works, but since I’m using <Link>
instead of <a>
for a lot of links, clicking those doesn’t clear everything and the p5.js sketch still continues to run. I would like to destroy the p5.js instance on the component lifecycle end. I am unable to find a method to completely destroy the instances. (to me, noLoop
just seems to have p5.js sit there, not actually completely stop)
Here is my code, for reference:
import * as React from "react";
import p5 from "p5";
type SketchWrapperParameterTypes = {
sketchFunc: (sketch: p5) => void;
// TODO: Figure out how to make node argument to p5 constructor happy
canvasID: any;
};
const SketchWrapper = ({
sketchFunc,
canvasID,
}: SketchWrapperParameterTypes): React.ReactElement => {
React.useEffect(() => {
console.info("Starting paint sketch");
new p5(sketchFunc, canvasID);
return () => {
console.warn("Stopping paint sketch");
// TODO: Destroy p5.js instance
// ??? What to do here ???
};
}, []);
return <div id={canvasID} className="container-fluid p-2 flex-grow-1"></div>;
};
export default SketchWrapper;
Here is how it would be used:
const page = (): React.ReactElement => {
const sketchElementId: string = "paintSketch";
const sketchFunc: (sketch: p5) => void = (sketch: p5) => {
sketch.setup = () => {
// ...
};
sketch.draw = () => {
// ...
console.debug("STILL RUNNING");
};
};
return (
/* ... */
<SketchWrapper sketchFunc={sketchFunc} canvasID={sketchElementId} />
/* ... */
);
};
If I were to click a <Link>
to somewhere, “STILL RUNNING” will still keep being logged, even though I can’t see the canvas anymore.