A component to integrate P5.js sketches into React apps.
Note: Version 5 is still in development, currently the
5.0.0-rc.xrange has been released for internal development or experimental testing ONLY. It is recommended to continue utilising version4.4.1until version5.0.0is out of thercversioning scheme.One other thing to note about the coming release of the version
5.x.xrange is that it will support thep5version2.x.xrange which means support forasyncandawaitin your sketches and much more besides, you can read more on the upcoming version of the P5 docs.
The main component for rendering p5 sketches in React depends on your version:
- Version 4 and earlier: use
ReactP5Wrapper. - Version 5 and later: use
P5Canvas.
Both components work in the same way.
Breaking changes in v5:
-
Component rename
ReactP5Wrapper→P5Canvas
-
Types
P5WrapperProps→P5CanvasPropsP5WrapperClassName→CanvasContainerClassName
To install, use the following command in the format appropriate to your chosen package manager:
[npm|yarn|pnpm] [install|add] p5 @p5-wrapper/reactPlease note that p5, react and react-dom are peer dependencies. Make sure
they are installed in your project before installing this package.
"peerDependencies": {
"p5": ">= 1.4.1",
"react": ">= 18.2.0",
"react-dom": ">= 18.2.0"
},
Version 5
"peerDependencies": {
"p5": ">= 2.0.0",
"react": ">= 19.0.0",
"react-dom": ">= 19.0.0"
},
If you would like to use Typescript, you should install p5 types in the
development environment:
[npm|yarn|pnpm] [install|add] -D @types/p5If you plan to use this component within a Next.js application, you should instead use our Next.js dynamic implementation instead. To do get started, you can run:
[npm|yarn|pnpm] [install|add] p5 @p5-wrapper/next @p5-wrapper/reactPlease continue reading these docs and also look at the Next.js dynamic implementation docs for further supporting information.
A live demo can be viewed at P5-wrapper.github.io/react.
The repository contains further examples.
To try them out for yourself fork the repository, be sure you have PNPM installed and then run the following:
git clone [email protected]:<your username>/react.git
cd react
pnpm install
pnpm preview
Then just open http://localhost:3001 in a browser.
import * as React from "react";
import { ReactP5Wrapper } from "@p5-wrapper/react";
function sketch(p5) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
return <ReactP5Wrapper sketch={sketch} />;
}
Version 5
import * as React from "react";
import { P5Canvas } from "@p5-wrapper/react";
function sketch(p5) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
return <P5Canvas sketch={sketch} />;
}
TypeScript sketches can be declared in two different ways, below you will find two ways to declare a sketch, both examples do the exact same thing.
In short though, the component requires you to pass a sketch prop. The
sketch prop is simply a function which takes a p5 instance as it's first and
only argument.
import * as React from "react";
import { P5CanvasInstance, ReactP5Wrapper } from "@p5-wrapper/react";
function sketch(p5: P5CanvasInstance) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
return <ReactP5Wrapper sketch={sketch} />;
}
Version 5
import * as React from "react";
import { P5Canvas, P5CanvasInstance } from "@p5-wrapper/react";
function sketch(p5: P5CanvasInstance) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
return <P5Canvas sketch={sketch} />;
}
Using the Sketch type has one nice benefit over using P5CanvasInstance and
that is that the p5 argument passed to the sketch function is auto-typed as a
P5CanvasInstance for you.
Side note:
In general, it comes down to personal preference as to how you declare your
sketches and there is nothing wrong with using the P5CanvasInstance manually
in a regular function declaration.
import * as React from "react";
import { ReactP5Wrapper, Sketch } from "@p5-wrapper/react";
const sketch: Sketch = p5 => {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
};
export function App() {
return <ReactP5Wrapper sketch={sketch} />;
}
Version 5
import * as React from "react";
import { P5Canvas, Sketch } from "@p5-wrapper/react";
const sketch: Sketch = p5 => {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
};
export function App() {
return <P5Canvas sketch={sketch} />;
}
We also support the use of Generics to add type definitions for your props. If
used, the props will be properly typed when the props are passed to the
updateWithProps method.
To utilise generics you can use one of two methods. In both of the examples
below, we create a custom internal type called MySketchProps which is a union
type of SketchProps and a custom type which has a rotation key applied to
it.
Side note:
We could also write the MySketchProps type as an interface to do exactly the
same thing if that is to your personal preference:
interface MySketchProps extends SketchProps {
rotation: number;
}
This means, in these examples, that when the rotation prop that is provided as
part of the props passed to the updateWithProps function, it will be
correctly typed as a number.
import {
P5CanvasInstance,
ReactP5Wrapper,
SketchProps
} from "@p5-wrapper/react";
import React, { useEffect, useState } from "react";
type MySketchProps = SketchProps & {
rotation: number;
};
function sketch(p5: P5CanvasInstance<MySketchProps>) {
let rotation = 0;
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.updateWithProps = props => {
if (props.rotation) {
rotation = (props.rotation * Math.PI) / 180;
}
};
p5.draw = () => {
p5.background(100);
p5.normalMaterial();
p5.noStroke();
p5.push();
p5.rotateY(rotation);
p5.box(100);
p5.pop();
};
}
export function App() {
const [rotation, setRotation] = useState(0);
useEffect(() => {
const interval = setInterval(
() => setRotation(rotation => rotation + 100),
100
);
return () => {
clearInterval(interval);
};
}, []);
return <ReactP5Wrapper sketch={sketch} rotation={rotation} />;
}
Version 5
import { P5Canvas, P5CanvasInstance, SketchProps } from "@p5-wrapper/react";
import React, { useEffect, useState } from "react";
type MySketchProps = SketchProps & {
rotation: number;
};
function sketch(p5: P5CanvasInstance<MySketchProps>) {
let rotation = 0;
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.updateWithProps = props => {
if (props.rotation) {
rotation = (props.rotation * Math.PI) / 180;
}
};
p5.draw = () => {
p5.background(100);
p5.normalMaterial();
p5.noStroke();
p5.push();
p5.rotateY(rotation);
p5.box(100);
p5.pop();
};
}
export function App() {
const [rotation, setRotation] = useState(0);
useEffect(() => {
const interval = setInterval(
() => setRotation(rotation => rotation + 100),
100
);
return () => {
clearInterval(interval);
};
}, []);
return <P5Canvas sketch={sketch} rotation={rotation} />;
}
import { ReactP5Wrapper, Sketch, SketchProps } from "@p5-wrapper/react";
import React, { useEffect, useState } from "react";
type MySketchProps = SketchProps & {
rotation: number;
};
const sketch: Sketch<MySketchProps> = p5 => {
let rotation = 0;
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.updateWithProps = props => {
if (props.rotation) {
rotation = (props.rotation * Math.PI) / 180;
}
};
p5.draw = () => {
p5.background(100);
p5.normalMaterial();
p5.noStroke();
p5.push();
p5.rotateY(rotation);
p5.box(100);
p5.pop();
};
};
export function App() {
const [rotation, setRotation] = useState(0);
useEffect(() => {
const interval = setInterval(
() => setRotation(rotation => rotation + 100),
100
);
return () => {
clearInterval(interval);
};
}, []);
return <ReactP5Wrapper sketch={sketch} rotation={rotation} />;
}
Version 5
import { P5Canvas, Sketch, SketchProps } from "@p5-wrapper/react";
import React, { useEffect, useState } from "react";
type MySketchProps = SketchProps & {
rotation: number;
};
const sketch: Sketch<MySketchProps> = p5 => {
let rotation = 0;
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.updateWithProps = props => {
if (props.rotation) {
rotation = (props.rotation * Math.PI) / 180;
}
};
p5.draw = () => {
p5.background(100);
p5.normalMaterial();
p5.noStroke();
p5.push();
p5.rotateY(rotation);
p5.box(100);
p5.pop();
};
};
export function App() {
const [rotation, setRotation] = useState(0);
useEffect(() => {
const interval = setInterval(
() => setRotation(rotation => rotation + 100),
100
);
return () => {
clearInterval(interval);
};
}, []);
return <P5Canvas sketch={sketch} rotation={rotation} />;
}
import * as React from "react";
import { ReactP5Wrapper } from "@p5-wrapper/react";
function setup(p5) {
return () => {
p5.createCanvas(600, 400, p5.WEBGL);
};
}
function draw(p5) {
return () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
function sketch(p5) {
p5.setup = setup(p5);
p5.draw = draw(p5);
}
export function App() {
return <ReactP5Wrapper sketch={sketch} />;
}
Version 5
import * as React from "react";
import { P5Canvas } from "@p5-wrapper/react";
function setup(p5) {
return () => {
p5.createCanvas(600, 400, p5.WEBGL);
};
}
function draw(p5) {
return () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
function sketch(p5) {
p5.setup = setup(p5);
p5.draw = draw(p5);
}
export function App() {
return <P5Canvas sketch={sketch} />;
}
The only required property is the sketch prop. The sketch prop is a function
that will be passed a p5 instance to use for rendering your sketches (see the
usage section above).
You can pass as many custom props as you want. These will be passed into the
updateWithProps method if you have defined it within your sketch.
In the below example you see the updateWithProps method being used. This is
called when the component initially renders and when the props passed to the
wrapper are changed, if it is set within your sketch. This way we can render our
component (ReactP5Wrapper in v4, or P5Canvas in v5) and react to component
prop changes directly within our sketches!
import { ReactP5Wrapper } from "@p5-wrapper/react";
import React, { useEffect, useState } from "react";
function sketch(p5) {
let rotation = 0;
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.updateWithProps = props => {
if (props.rotation) {
rotation = (props.rotation * Math.PI) / 180;
}
};
p5.draw = () => {
p5.background(100);
p5.normalMaterial();
p5.noStroke();
p5.push();
p5.rotateY(rotation);
p5.box(100);
p5.pop();
};
}
export function App() {
const [rotation, setRotation] = useState(0);
useEffect(() => {
const interval = setInterval(
() => setRotation(rotation => rotation + 100),
100
);
return () => {
clearInterval(interval);
};
}, []);
return <ReactP5Wrapper sketch={sketch} rotation={rotation} />;
}
Version 5
import { P5Canvas } from "@p5-wrapper/react";
import React, { useEffect, useState } from "react";
function sketch(p5) {
let rotation = 0;
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.updateWithProps = props => {
if (props.rotation) {
rotation = (props.rotation * Math.PI) / 180;
}
};
p5.draw = () => {
p5.background(100);
p5.normalMaterial();
p5.noStroke();
p5.push();
p5.rotateY(rotation);
p5.box(100);
p5.pop();
};
}
export function App() {
const [rotation, setRotation] = useState(0);
useEffect(() => {
const interval = setInterval(
() => setRotation(rotation => rotation + 100),
100
);
return () => {
clearInterval(interval);
};
}, []);
return <P5Canvas sketch={sketch} rotation={rotation} />;
}
To render a component on top of the sketch, you can add it as a child of the
component (ReactP5Wrapper in v4, or P5Canvas in v5) and then use the
exported constant (P5WrapperClassName in v4, or CanvasContainerClassName in
v5) in your css-in-js library of choice to style one element above the other via
css.
For instance, using styled components, we could
center some text on top of our sketch like so:
import { P5WrapperClassName, ReactP5Wrapper } from "@p5-wrapper/react";
import styled, { createGlobalStyle } from "styled-components";
const GlobalWrapperStyles = createGlobalStyle`
.${P5WrapperClassName} {
position: relative;
}
`;
const StyledCentredText = styled.span`
.${P5WrapperClassName} & {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 2rem;
margin: 0;
text-align: center;
}
`;
export function App() {
const [rotation, setRotation] = useState(0);
useEffect(() => {
const interval = setInterval(
() => setRotation(rotation => rotation + 100),
100
);
return () => {
clearInterval(interval);
};
}, []);
return (
<Fragment>
<GlobalWrapperStyles />
<ReactP5Wrapper sketch={sketch} rotation={rotation}>
<StyledCentredText>Hello world!</StyledCentredText>
</ReactP5Wrapper>
</Fragment>
);
}
Version 5
import { CanvasContainerClassName, P5Canvas } from "@p5-wrapper/react";
import styled, { createGlobalStyle } from "styled-components";
const GlobalWrapperStyles = createGlobalStyle`
.${CanvasContainerClassName} {
position: relative;
}
`;
const StyledCentredText = styled.span`
.${CanvasContainerClassName} & {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 2rem;
margin: 0;
text-align: center;
}
`;
export function App() {
const [rotation, setRotation] = useState(0);
useEffect(() => {
const interval = setInterval(
() => setRotation(rotation => rotation + 100),
100
);
return () => {
clearInterval(interval);
};
}, []);
return (
<Fragment>
<GlobalWrapperStyles />
<P5Canvas sketch={sketch} rotation={rotation}>
<StyledCentredText>Hello world!</StyledCentredText>
</P5Canvas>
</Fragment>
);
}
Of course, you can also use any other css-in-js library or by just using simple
css to achieve almost anything you can imagine just by using the wrapper class
as your root selector.
Lets say you want to have a fallback UI in case the sketch ever falls out of
sync or is undefined for some reason. If this is a use case for you then you
call use the fallback prop to provide the necessary UI to show in the case
that the sketch becomes undefined. An example could be as follows:
import * as React from "react";
import { ReactP5Wrapper } from "@p5-wrapper/react";
function sketchOne(p5) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
function sketchTwo(p5) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(500);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
const [sketch, setSketch] = React.useState(undefined);
const chooseNothing = () => setSketch(undefined);
const chooseSketchOne = () => setSketch(sketchOne);
const chooseSketchTwo = () => setSketch(sketchTwo);
return (
<>
<ul>
<li>
<button onClick={chooseNothing}>Choose nothing</button>
</li>
<li>
<button onClick={chooseSketchOne}>Choose sketch 1</button>
</li>
<li>
<button onClick={chooseSketchTwo}>Choose sketch 2</button>
</li>
</ul>
<ReactP5Wrapper
fallback={<h1>No sketch selected yet.</h1>}
sketch={sketch}
/>
</>
);
}
Version 5
import * as React from "react";
import { P5Canvas } from "@p5-wrapper/react";
function sketchOne(p5) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
function sketchTwo(p5) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(500);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
const [sketch, setSketch] = React.useState(undefined);
const chooseNothing = () => setSketch(undefined);
const chooseSketchOne = () => setSketch(sketchOne);
const chooseSketchTwo = () => setSketch(sketchTwo);
return (
<>
<ul>
<li>
<button onClick={chooseNothing}>Choose nothing</button>
</li>
<li>
<button onClick={chooseSketchOne}>Choose sketch 1</button>
</li>
<li>
<button onClick={chooseSketchTwo}>Choose sketch 2</button>
</li>
</ul>
<P5Canvas fallback={<h1>No sketch selected yet.</h1>} sketch={sketch} />
</>
);
}
In this case, by default the fallback UI containing
<h1>No sketch selected yet.</h1> will be rendered, then if you select a
sketch, it will be rendered until you choose to once again "show nothing" which
falls back to the fallback UI.
Since version 4.4.0, it was possible to add a fallback prop, see the section
on fallbacks.
Since version 5 it is now possible to pass an error and loading prop to the
wrapper which allow the user to pass different UIs for error and loading states.
- The
error state will trigger if the sketch or the wrapper encounter an
issue, otherwise a default error view will be shown.
- The
loading state will trigger while the wrapper is being lazy loaded,
otherwise a default loading view will be shown.
To show a custom UI when an error occurs within the sketch or the wrapper, you
can pass a lazy function to the error prop.
import * as React from "react";
import { P5CanvasInstance, ReactP5Wrapper } from "@p5-wrapper/react";
// This child will throw an error, oh no!
function ErrorChild() {
throw new Error("oops");
}
// This view will catch the thrown error and give you access to what exactly was thrown.
function ErrorUI(error: any) {
if (error instanceof Error) {
return <p>An error occured: {error.message}</p>;
}
return <p>An unknown error occured: {error.toString()}</p>;
}
function sketch(p5: P5CanvasInstance) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
return (
<ReactP5Wrapper sketch={sketch} error={ErrorUI}>
<ErrorChild />
</ReactP5Wrapper>
);
}
Version 5
import * as React from "react";
import { P5Canvas, P5CanvasInstance } from "@p5-wrapper/react";
// This child will throw an error, oh no!
function ErrorChild() {
throw new Error("oops");
}
// This view will catch the thrown error and give you access to what exactly was thrown.
function ErrorUI(error: any) {
if (error instanceof Error) {
return <p>An error occured: {error.message}</p>;
}
return <p>An unknown error occured: {error.toString()}</p>;
}
function sketch(p5: P5CanvasInstance) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
return (
<P5Canvas sketch={sketch} error={ErrorUI}>
<ErrorChild />
</P5Canvas>
);
}
Instead of the sketch, this will render <p>An error occured: oops</p>. Note
that in truth, the ErrorView will always receive any values since JS /
TS allow you to throw whatever values you want to, this is why we have to add
the error instanceof Error check to be sure the value we got was actually an
Error instance and not some other value like a number, string, object or
anything else that could be thrown by JS / TS.
As mentioned above, the error state will trigger if the sketch or the wrapper
encounter an issue, otherwise a default error view will be shown.
To show a custom UI while the sketch UI is being lazy loaded, you can pass a
lazy function to the loading prop.
import * as React from "react";
import { P5CanvasInstance, ReactP5Wrapper } from "@p5-wrapper/react";
function LoadingUI() {
return <p>The sketch is being loaded.</p>;
}
function sketch(p5: P5CanvasInstance) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
return <ReactP5Wrapper sketch={sketch} loading={LoadingUI} />;
}
Version 5
import * as React from "react";
import { P5Canvas, P5CanvasInstance } from "@p5-wrapper/react";
function LoadingUI() {
return <p>The sketch is being loaded.</p>;
}
function sketch(p5: P5CanvasInstance) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
return <P5Canvas sketch={sketch} loading={LoadingUI} />;
}
In the initial period between the sketch render starting and it's lazy loading
ending, the LoadingUI will be shown!
As mentioned above, the loading state will trigger while the wrapper is being
lazy loaded, otherwise a default loading view will be shown.
As discussed in multiple issues such as
#11,
#23,
#61 and
#62, there seems to be
confusion as to how we can use P5 plugins and constructors out of the box. This
section aims to clarify these!
Since P5 is being used in
P5 instance mode
as part of this project, P5 will not automatically load global plugins like it
usually might in global mode.
Let's say we want to use the
P5 sound plugin in our
component, we could do the following:
import * as p5 from "p5";
import { ReactP5Wrapper, Sketch } from "@p5-wrapper/react";
import React, { useEffect, useState } from "react";
(window as any).p5 = p5;
await import("p5/lib/addons/p5.sound");
const sketch: Sketch = p5 => {
let song: p5.SoundFile;
let button: p5.Element;
p5.setup = () => {
p5.createCanvas(600, 400, p5.WEBGL);
p5.background(255, 0, 0);
button = p5.createButton("Toggle audio");
button.mousePressed(() => {
if (!song) {
const songPath = "/piano.mp3";
song = p5.loadSound(
songPath,
() => {
song.play();
},
() => {
console.error(
`Could not load the requested sound file ${songPath}`
);
}
);
return;
}
if (!song.isPlaying()) {
song.play();
return;
}
song.pause();
});
};
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
};
export default function App() {
return <ReactP5Wrapper sketch={sketch} />;
}
Version 5
import * as p5 from "p5";
import { P5Canvas, Sketch } from "@p5-wrapper/react";
import React, { useEffect, useState } from "react";
(window as any).p5 = p5;
await import("p5/lib/addons/p5.sound");
const sketch: Sketch = p5 => {
let song: p5.SoundFile;
let button: p5.Element;
p5.setup = () => {
p5.createCanvas(600, 400, p5.WEBGL);
p5.background(255, 0, 0);
button = p5.createButton("Toggle audio");
button.mousePressed(() => {
if (!song) {
const songPath = "/piano.mp3";
song = p5.loadSound(
songPath,
() => {
song.play();
},
() => {
console.error(
`Could not load the requested sound file ${songPath}`
);
}
);
return;
}
if (!song.isPlaying()) {
song.play();
return;
}
song.pause();
});
};
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
};
export default function App() {
return <P5Canvas sketch={sketch} />;
}
In this Typescript + React example, we can see a few key things.
- Firstly we need to set
p5 on the window object manually. This is because
p5.sound requires that it be executed client side only AND that p5 be
available BEFORE it is imported into the global (window) scope.
- Secondly, we ensure that audio is played after a user action, in our case this
happens on a button click. This is because in some browsers, without waiting
for a user interaction before playing audio, the audio will be blocked by the
browser from playing at all.
- Thirdly and relevant especially to Safari users, Safari blocks audio from all
tabs by default, you will need to manually change this setting in your Safari
settings. This could affect other browsers but sadly this is a browser
decision and until P5 Sound is
updated to support newer audio APIs and browser requirements. This could
happen at anytime in other places and is a
P5 Sound issue most generally
because it does not ask for permissions by default, even though browsers have
been requiring it for some time.
Note: The above example requires support for
top level await,
dynamic import statements and
the stream API to be supported in your browser.
Furthermore, the stream API built into the
browser requires that HTTPS is used to ensure secure data transmission.
To access P5 constructors such as p5.Vector or p5.Envelope, you need to use
the instance mode syntax instead. For example:
Constructor
Global mode accessor
Instance mode accessor
Vector
p5.Vector
p5.constructor.Vector
Envelope
p5.Envelope
p5.constructor.Envelope
So now that we know this, let's imagine we want a random 2D Vector instance. In
our sketch function we would simply call p5.constructor.Vector.random2D()
instead of p5.Vector.random2D(). This is because of how the
P5 instance mode
was implemented by the P5 team. While I am not sure why they decided to change
the API for instance mode specifically, it is still quite simple to use the
constructs we are used to without much extra work involved.
NOTE: The source code for the component is in the src directory.
To build, watch and serve the examples which will also watch the component
source, run:
pnpm preview
react's People
Forkers
pingf
derekkinsman
kandizzy
au-re
motleyagency
slin12
sjorsvanheuveln
netspencer
hifilorau
skywickenden
mosesoak
mkavarts
josipreh
baileytincher
sixman9
iamnamxd
italoadler
cubeofcheese
trafnar
itsgk93
luke9389
albererre
markfuller1
grountish
ajnovember
stephenroddy
guadalupebabio
markdenardo
jiixing
julienbrg
jupyterjones
jackpetersen2
xinjuren10
georgethomastodd
junruchen
gitlabcloud
jhrtn
manolara
rohanchkrabrty
munshkr
jeukhwang
yevdyko
taardenn
qanpi
u1-mas
adriancancode
rainwaters11
kikidotdirectory
0x0arash
react's Issues
Trying to include vanilla .js class
Hi, first of all I'd like to say this is the best p5 react wrapper so far! @and-who
I'm new to all these, so do give me some guidance here.
I'm trying to create create a simple particle system here.
My particle class
`
import p5 from "p5";
export default class Particle {
constructor() {
this.x = random(width);
this.y = random(height);
this.diameter = random(10, 30);
this.speed = 1;
}
move() {
this.x += random(-this.speed, this.speed);
this.y += random(-this.speed, this.speed);
}
display() {
ellipse(this.x, this.y, this.diameter, this.diameter);
}
}
`
My p5 sketch
`
import p5 from "p5";
import Particle from "./Particle";
global.p5 = p5;
export default function sketch(p) {
let bug1;
let bug2;
p.setup = () => {
p.createCanvas(710, 400);
bug1 = new Particle();
bug2 = new Particle();
};
p.draw = () => {
p.background(50, 89, 100);
bug1.move();
bug1.display();
bug2.move();
bug2.display();
};
}
`
But I can't seem to get it working...
[Question] Is it possible to create an interactive robotic arm control?
Hello,
I'm part of my robotics club at my university and am tasked with finding a way to provide a way to control our robotic arm. I've been looking at other JS libraries like EaselJS and Paper.js, etc. But I wanted to know if it would be possible to mimic the interactivity with P5.js & React.js as seen in this gif: http://www.alistairwick.com/assets/images/robot/ik.gif
Anyways, I just need to be able to create an interactive way to provide 1 to 1 arm control for now. And if I figure things out for inverse kinematics than the setup of the controls should be pretty similar. We can assume the robotic arm I'm working on is a 3 degree of freedom arm as seen in the gif.
Thanks so much!
Slow Performance when switching sketches
Context
I have a simple App that switches between sketches on click:
code: https://github.com/michaelghinrichs/i-hope-this-art
example: https://michaelghinrichs.github.io/i-hope-this-art/
Problem
I have started to notice if i switch between sketches (click the screen 10 times thus changing the current sketch 10 times) the canvas starts to get really really slow... try it out on the site and notice that the drawings render very slowly in a direct correlation to how many times you have switched sketches.
What I am doing wrong?
Currently, i just pass a different function to sketch, is that a bad practice? Should each sketch be it's own p5 wrapper?
Here is what my code looks like:
import React, { Component } from 'react';
import P5Wrapper from 'react-p5-wrapper';
import doubleCircles from './drawings/doubleCircles';
import contours from './drawings/contours';
import flower from './drawings/flower';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
sketches: [ contours, flower, doubleCircles ],
active: flower,
}
}
switchSketch = () => {
const current = this.state.active;
const nextSketchs = this.state.sketches.filter((sketch) => {
return sketch.name !== current.name;
});
const newSketchs = nextSketchs.concat(current);
this.setState({
active: nextSketchs[0],
sketches: newSketchs,
});
}
render() {
return (
<div className="App" onClick={this.switchSketch}>
<P5Wrapper sketch={this.state.active} />
</div>
);
}
}
Any idea what I am doing wrong? Should I unmount and remount the P5Wrapper?
pure component?
Can you make this a PureComponent instead of a Component? I've had a little play with it as a purecomponent, and it works all the same, but it doesn't re-rendering unnecessarily. I was having issues when my parent element updated, as it would cause all of its child elements to re-render (which, for p5, means re-initialising the sketch). I would make a pull request for this but it seems silly for just one word.
Thanks, Lewis
does not work with isomorphic react apps
Unfortunately p5 won't work with isomorphic react apps due to window and documentrequirements. Any thoughts?
how to use it with Reactjs
I have followed instructions as you said, I am novice currently learning react js but I know processing and p5.
I have implement a visualizer in web app
so here is my minimal code.
import React, { Component } from 'react';
import {DropdownButton, MenuItem, Button, Container, Row, Col} from 'react-bootstrap';
import { Line } from "react-chartjs";
import logo from './logo.svg';
import './App.css';
import P5Wrapper from 'react-p5-wrapper';
class App extends Component {
render() {
var time="Evening";
var userName="Shirish";
return (
<div className="App">
<P5Wrapper sketch={sketch} />
</div>
);
}
}
export default function sketch (p) {
let rotation = 0;
p.setup = function () {
p.createCanvas(600, 400, p.WEBGL);
};
p.myCustomRedrawAccordingToNewPropsHandler = function (props) {
if (props.rotation){
rotation = props.rotation * Math.PI / 180;
}
};
p.draw = function () {
p.background(100);
p.noStroke();
p.push();
p.rotateY(rotation);
p.box(100);
p.pop();
};
};
export default App;
I get
./src/App.js
Syntax error: Only one default export allowed per module. (182:0)
I think I am not sure of this function. where should it reside ? in main app file? I also think this is no in same langauge also.
Dependency is at 0.0.5 but verion is still 0.0.4
i can only use version 0.0.4. when i try to use .5 it says "version not found"
Rotation animation not working
Using React 16.13.1
npm 6.14.4
Node v12.16.0
P5 1.0.0
I've created a component to place a sketch in, which is displaying a single frame of the sketch, but that's it. The animation of the included sketches based on the "rotation" property isn't updating.
I'm using both example sketchs (sketch1.js and sketch2.js, as well as the example in the README file -- all have the same behavior.
App.js:
import React from 'react';
import BackgroundAnimation from './BackgroundAnimation';
function App() {
return (
< BackgroundAnimation />
)
}
export default App;
`
BackgroundAnimation.js:
`
import React from 'react';
import P5Wrapper from 'react-p5-wrapper';
import {default as sketch1} from './sketches/sketch1';
const BackgroundAnimation = () => {
let rotation = 10;
return (
<P5Wrapper sketch={sketch2} rotation={rotation} />
)
}
export default BackgroundAnimation;
`
I've added some console.log(), which appear to never be called (Not seeing anything in the console).
I'm still a little new to React. I'm guessing I have to add something to one of the life cycle functions? Maybe I can't use functional components and need to explicitly make it a class component? Are there any hooks I could use? I'm not seeing much documentation.
Any help would be greatly appreciated.
Thanks in advance.
Reference error in new version (1.2.0)
How to load plugins with this?
Is there a way to load p5 plugins using this wrapper?
cannot use imageMode() etc.
When using a sketch in a REACT Webapp (via react-p5-wrapper), when I try to use:
p.imageMode(CENTER)
I get the error:
'CENTER' is not defined
Any suggestions?
Can't use in project (Create ReactApp)
I'm attempting to create a sketch file using your method but I'm getting this error:
Module not found: Can't resolve 'p5' in '/node_modules/react-p5-wrapper/dist'.
Do I need to create a browserfy build of p5 or something?
Please help!
Issue with p5.play add on?
Hi, I'm working on a p5 game that requires p5.play library. Since it's not in the ecosystem, I dragged the p5.play into the p5 node_module and use 'import "p5/lib/addons/p5.play"; to import it. However, I still can't use the p5.play function. Can anyone help me solve it?
Thanks!
Update: I forgot to import * as p5 from 'p5' - it also only works for react-p5-wrapper but not react-p5 somehow :(
p5.sound import issue
Hi. I include import "p5/lib/addons/p5.sound" in sketch.js and I get a compile error Line 21: 'loadSound' is not defined no-undef.
Line 21 is: let song = loadSound("/src/test.ogg");
Is there anything I did wrong?
Thank you
GitHub Pages link dead (404)
The link in the README goes to a 404 page: "There isn't a GitHub Pages site here."
http://nerocor.github.io/react-p5-wrapper/
Using https also gives a 404.
Any plans to implement react hooks?
Are there any future plans to refactor the code to use hooks and all the latest React goodness? I found one here which looks very promising but it's way to complex for a novice like me. https://discourse.processing.org/t/using-react-with-p5-js-es6-support/
Expand to include p5 libraries/addons eg p5.sound
Currently only the basic p5 is wrapped.
It is not clear how to include the libraries that sit in "p5\lib\addons".
react-p5-wrapper and minified p5.js
Question: does the react-p5-wrapper use the minified version of p5.js (p5.min.js) ?
And if not, is there a way to force it to ?
p.text() not displaying
I have been trying everything I could think of to get the canvas to display text. I have changed the location many times and the colors. I cannot figure out why it isn't working. I can display a rectangle and ellipse, but for some reason text won't show. I will provide any more information necessary. Thank you for your help.
p.setup = function () {
p.createCanvas(window.innerWidth, window.innerHeight*.75, p.WEBGL);
p.background(100);
p.strokeWeight(1);
p.stroke(color);
p.cursor(p.CROSS);
};
p.draw = function () {
p.fill(255);
p.textSize(32);
p.text('Sample Text', 0, 0);
}
ClassName prop
It would be nice to be able to pass a className prop to style the wrapper div directly.
example sketch produces TypeError: curFillShader.attributes.aNormal is undefined
Dependencies:
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-p5-wrapper": "^0.0.4",
"react-scripts": "1.1.1",
Error message:
TypeError: this.curFillShader.attributes.aNormal is undefined
./node_modules/p5/lib/p5.js/</</<[105]</p5.RendererGL.prototype.createBuffers
node_modules/p5/lib/p5.js:68869
68866 | // allocate space for normals
68867 | this._bindBuffer(this.gHash[gId].normalBuffer, gl.ARRAY_BUFFER,
68868 | this._vToNArray(obj.vertexNormals), Float32Array, gl.STATIC_DRAW);
> 68869 | this.curFillShader.enableAttrib(this.curFillShader.attributes.aNormal.location,
68870 | 3, gl.FLOAT, false, 0, 0);
68871 | // tex coords
68872 | this._bindBuffer(this.gHash[gId].uvBuffer, gl.ARRAY_BUFFER,
./node_modules/p5/lib/p5.js/</</<[105]</p5.RendererGL.prototype.createBuffers
node_modules/p5/lib/p5.js:68869
68866 | // allocate space for normals
68867 | this._bindBuffer(this.gHash[gId].normalBuffer, gl.ARRAY_BUFFER,
68868 | this._vToNArray(obj.vertexNormals), Float32Array, gl.STATIC_DRAW);
> 68869 | this.curFillShader.enableAttrib(this.curFillShader.attributes.aNormal.location,
68870 | 3, gl.FLOAT, false, 0, 0);
68871 | // tex coords
68872 | this._bindBuffer(this.gHash[gId].uvBuffer, gl.ARRAY_BUFFER,
./node_modules/p5/lib/p5.js/</</<[109]</p5.prototype.box
node_modules/p5/lib/p5.js:70681
70678 | //initialize our geometry buffer with
70679 | //the key val pair:
70680 | //geometry Id, Geom object
> 70681 | this._renderer.createBuffers(gId, boxGeom);
70682 | }
70683 | this._renderer.drawBuffers(gId);
70684 |
sketch/p.draw
src/sketches/default.js:22
19 | p.translate(-150, 100);
20 | p.rotateY(rotation);
21 | p.rotateX(-0.9);
> 22 | p.box(100);
23 | p.pop();
24 |
25 | p.noFill();
How to set sandbox="allow-downloads"?
I've created a prototype that allows the user to download a file to their local machine once they're done with manipulation.
Essentially I'm trying to re-create this by going through this tutorial in React https://www.youtube.com/watch?v=JWsKay58Z2g&list=PLRqwX-V7Uu6YPSwT06y_AEYTqIwbeam3y&index=12
However in Chrome I'm getting this error saying...
Download is disallowed. The frame initiating or instantiating the download is sandboxed, but the flag ‘allow-downloads’ is not set. See https://www.chromestatus.com/feature/5706745674465280 for more details.
After Google, it seems this is something new they just released. However we can opt in.
I wonder if anyone know how to set allow-downloads in my sandbox attribute?
Unmet peer dependency.
I get this warning when installing into React v15.4.2:
├── UNMET PEER DEPENDENCY [email protected]
└── [email protected]
npm WARN [email protected] requires a peer of react@^0.14.0 but none was installed.
My package.json looks like this:
{
/* stuff */
"dependencies": {
"react": "15.4.2",
/* everything else */
}
}
Navigating away from a route that uses react-p5-wrapper is crashing my app
Hey!
I am using react-p5-wrapper in a web app called TruSat, thank you for building it!
https://trusat.org/catalog/priorities
The little badges in the table rows are rendered with help of your wrapper. The number of the sat is used to conditionally render a different colored badge for each.
I just found a weird bug whereby the app crashes (sometimes) when I click on a users name in the table to navigate to their profile page.
When on the link I shared above, try clicking on the user named SolarLyra in the table (last column on right) and you will see that their profile page doesn't load - but it does when you refresh the page. If you can't replicate the bug, try repeating this process a couple of times by going back to the catalog page and click the username again in the table.
When I check the console, I see the following error:
TypeError: Cannot read property 'remove' of null
at t.componentWillUnmount
And upon further inspection, it originates to here-
P5Wrapper.prototype.componentWillUnmount = function () {
this.state.canvas.remove();
};
Any ideas what I can do on my end to help fix this bug?
Thanks so much in advance!
John.
npm start fails due to issues in a dependency
Will be fixed with JedWatson/react-component-gulp-tasks#30 if it ever gets merged.
Running into an issue with Gatsby.js, "Window is not defined"
Was wondering if anyone else was running into this problem with Gatsby.js. I am getting a "Window is not defined error" when trying to build with p5 and react-p5-wrapper. It seems like the "window" is actually in the p5.js file. I can currently run in on the local server, just can't build the Gatsby app.
Cannot read property 'angleBetween' of undefined
I output the incoming function inside the p5, found no p5.Vector,can you fix it
Passing props to sketch function
Hello there,
i have a sketch function ( same as the one on the first example) and i want to pass some props to this function and i cant understand how.
So i have the index.js file which is something like this
`import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import P5Wrapper from 'react-p5-wrapper';
import sketch from './demo';
class App extends Component {
state = {
x: undefined,
y: undefined
}
onMove(e){
this.setState({x:e.screenX, y: e.screenY})
}
render() {
return (
<div className="App" onMouseMove={(e) => this.onMove(e)}>
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
<P5Wrapper sketch={sketch} />
</p>
</div>
);
}
}
export default App;`
and my sketch function is this
`
export default function sketch (p) {
let rotation = 0;
p.setup = function () {
p.createCanvas(800, 800, p.WEBGL);
p.angleMode('DEGREES');
};
p.myCustomRedrawAccordingToNewPropsHandler = function (props) {
if (props.rotation){
rotation = props.rotation * Math.PI / 180;
}
};
p.draw = function () {
p.background(100);
p.stroke(255);
p.push();
p.rotateX(rotation);
// p.box(100);
p.fill(255);
// p.rotate(10);
p.translate(props.x,props.y);
p.rect(0,0,100,50);
p.pop();
};
};`
now as you can see i want to pass down x and y to my sketch, but i can't figure out how
p5 costants seems to be unrecognized
Sorry to bother, I'm trying to use you super-helpful component BUT when I use p5 costants like PI or HALF_PI I recive un error of undefined am I the only? there is a way to fix this?
How to style the canvas element in React?
The canvas is wrapped in unmarked div tags.
<div>
<canvas>
</div>
Is there a way to apply styles to the canvas so I can manipulate it as a background of another element (position: 'absolute', top: 0, left: 0, zIndex: -1)? So far, my react styling does nothing but push the canvas down.
Additional info, I would like to be able to do this without needing an external css file. So far, I have the and it would be great if I can somehow manipulate it's zIndex, position, and all other typical canvas styles.
How do you incorporate a p5 Sketch file with additional .js files
There are a few p5 tutorials out there that have additional .js files they use to import in for the p5 experience.
I'm trying to follow this tutorial here: https://thecodingtrain.com/CodingChallenges/115-snake-game-redux.html
Re-creating the exact same thing in React by copy-pasting the code.
But to get it to work with React-p5-wrapper and React in general seems hard?
Here is my demo code.
https://codesandbox.io/s/immutable-wave-z20tv?file=/src/App.js
UPDATE: I think I manage to fix it but I'm getting a ton of console errors which I don't quite understand.
Passing initialisation values
The myCustomRedrawAccordingToNewPropsHandler works fine for taking new property values which have been changed, but it doesn't take their initial values. E.g. with the README example, rotation has been set to 0 initially from within the sketch, instead of via the <P5Wrapper sketch={sketch} rotation={rotation}/> code.
Is there a hack for this? Or does it need to be implemented? I find that being able to send values to the sketch (and have them be received from the start) is extremely important when wanting to dynamically allocate config values to sketches, like the urls of source data.
Drawing new line instead of updating existing one
Hi,
i'm trying to draw a rainfall.
If i do this on p5online editor it works, it creates a single rain drop that falls over the screen.
If i use this with p5wrapper it draws multiple drops one under the other every call of "draw" function.
Here's my sketch :
`import RainDrop from '../Models/RainDrop'
export default function sketch (p) {
const drop = new RainDrop(p)
p.setup = function () {
p.createCanvas(window.innerWidth, window.innerHeight)
};
p.myCustomRedrawAccordingToNewPropsHandler = function (props) {
console.log(props, 'custom thing')
};
p.draw = function () {
drop.draw()
drop.update()
};
};`
here's my RainDrop class
`export default class RainDrop {
constructor(p) {
this.x = Math.floor(Math.random() * window.innerWidth) + 1
//this.y = Math.floor(Math.random() * -500)
this.y = 50
this.speed = Math.floor(Math.random() * 10) + 1
this.p = p
}
update = () => {
this.y = this.y + 10//this.speed
if(this.y > window.innerHeight) {
this.y = Math.floor(Math.random() * -500)
}
}
draw = () => {
this.p.stroke(128,0,128)
this.p.line(this.x, this.y, this.x, this.y + 5)
}
}`
and here's my simple App.js :
`import React from 'react';
import logo from './logo.svg';
import './App.css';
import P5Wrapper from 'react-p5-wrapper'
import MouseSketch from './Sketches/MouseSketch'
import RainingSketch from './Sketches/RainingSketch'
function App() {
return (
<div className="App">
<P5Wrapper sketch={RainingSketch} />
</div>
);
}
export default App;`
How do you pass value in props over to a vanilla .js class?
Currently I've this in my Sketch.tsx
p.myCustomRedrawAccordingToNewPropsHandler = function(props) { if (props.testValue) { testValue = props.testValue } }
Let's say I've a vanilla .js class file where I use it to generate particles.
How can I pass the testValue over to the .js file?
I tried to pass it into the constructor but it doesn't work?
It gives me "undefined".
How can I return the props value in p.myCustomRedrawAccordingToNewPropsHandler and store it somewhere else where I can reuse? It works in draw() but not setup().
TypeError: Cannot read property 'random2D' of undefined
Good morning my friends
How to use the Vector method, see that in the sketch argument an object is returned and not the p5 function that has the Vector method
= This Work
import React from "react";
import ReactDOM from "react-dom";
import P5Wrapper from "react-p5-wrapper";
export function sketch(p5) {
// let v1 = p5.Vector.random2D();
p5.setup = () => {
console.log("p.setup");
};
p5.draw = () => {
console.log("p.draw");
p5.background(240);
};
}
const App = () => {
return (
<>
<div>App Hello World!</div>{" "}
<div id="container_3d" className="center">
<P5Wrapper sketch={sketch} />
</div>
</>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
= This Not Work
import React from "react";
import ReactDOM from "react-dom";
import P5Wrapper from "react-p5-wrapper";
export function sketch(p5) {
console.log("typeof p5", typeof p5); // Not is a Function ???
console.log("p5", p5);
let v1 = p5.Vector.random2D(); // Error: index.js:6 Uncaught TypeError: Cannot read property 'random2D' of undefined
p5.setup = () => {
console.log("p.setup");
};
p5.draw = () => {
console.log("p.draw");
p5.background(240);
};
}
const App = () => {
return (
<>
<div>App Hello World!</div>{" "}
<div id="container_3d" className="center">
<P5Wrapper sketch={sketch} />
</div>
</>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
I can't use React hooks inside of the Sketch file?
When I try to run React hooks, I get a bunch of errors:
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
I'm trying to use React hooks within here:
export default function sketch(p5) {
...
}
"window not defined" error in NextJS app
This happens because p5 is imported before window is defined (e.g. server-side rendering and build step). By moving the require("p5") line into componentDidMount this can be resolved.
Component destroyed
Please, do something with componentWillUnmount to stop the sketch. Without this, the sketch still working and invoking prop functions even though it was destroyed.
How do you include p5.sound?
Not sure the ethics of submitting an issue. (let me know!)
But since the previous one has been closed, instead of tagging on questions there, I thought I should create a new one.
@jamesrweb I'm trying to get this working, just want to understand the step-by-step way of getting this working.
- Do I need to first
npm install --save @types/p5
- Can I just add
import * as p5 from "p5" and import "p5/lib/addons/p5.sound" in my Sketch file and use it straightaway?
My code, following this tutorial: https://www.youtube.com/watch?v=8HEgeAbYphA&feature=emb_logo
export default function sketch(p5) {
p5.setup = () => {
p5.createCanvas(400, 400)
env = new p5.Envelope()
env.setADSR(0.05, 0.1, 0.5, 1)
env.setRange(1.2, 0)
wave = new p5.Oscillator()
wave.setType("sine")
wave.start()
wave.freq(440)
wave.amp(env)
...
I tried them and I get the errors saying:

Originally posted by @vennsoh in #11 (comment)
How do you pass a value from your Sketch file back to your React component?
Hi there, I'm wondering if there's a way to pass a value from the p5 Sketch file back into React? For example. I want to keep track of the label value generated in p5 Sketch and use that somewhere later. How can I store that value globally?
export default function sketch(p5) {
const [store, setStore] = useStore()
function modelReady() {
console.log("Model is ready!!!")
mobilenet.predict(gotResults)
}
function gotResults(error, results) {
if (error) {
console.error(error)
} else {
**label = results[0].label**
mobilenet.predict(gotResults)
}
}
Pass function as property?
Can I also pass a function as a property let's say something like this:
<P5Wrapper sketch={sketch} action={actionFunction} />
//sketch
export function sketch(P) {
const p = P;
p.setup = function (props) {
p.createCanvas(width, height);
props.actionFunction();
};
p.draw = function () {
}
};
}
I've tried and failed. Is it possible to do this?
How to use p5.Vector.random2D() static method?
If I'm trying to use static method like p5.Vector.random2D() https://p5js.org/reference/#/p5.Vector/random2D
How can I use it?
import p5 from "p5" export default function sketch(p) { p.setup = () => { } p.draw = () => { p.background(240) let v1 = p5.Vector.random2D() } }
Dynamically change of sketch
I tried to change the sketch during a state rerender, but it keeps rendering the initial sketch. Any workarounds to change the sketch after the component has already been mounted?
support typescript?
can you support the typescript ?
Loading images with require
I could be doing something wrong here, but how could I pass images to p5 here?
Component
const myImage = require('./assets/image.png');
render() (
<P5Wrapper sketch={sketch} image={myImage}/>
)
sketch.js
let image;
p.myCustomRedrawAccordingToNewPropsHandler = function(props) {
if(props.image) {
image = props.image;
}
}
p.draw = function() {
p.loadImage(image); // p5.js says: It looks like there was a problem loading your image. Try checking if the file path [/static/media/image_1.01b571ff.png] is correct...
}
p5 js in react : Expected an assignment or function call and instead saw an expression no-unused-expressions
When running this script on p5 js's sandbox it's working really fine
When trying to use it inside react i get : Expected an assignment or function call and instead saw an expression no-unused-expressions
I checked previous questions and found out that most of the problems are syntax ones due to not using brackets or semicolons . I did all the good syntax practices but didn't get to make it function
Here is my sketch code on react :
export default function sketch(p){
var t;
var canvas ;
var w = window.innerWidth;
var h = window.innerHeight;
var x , y , d , T;
p.setup=()=>{
// put setup code here
t=0;
}
p.draw = () => {
canvas =p.createCanvas(w-50, h-50);
canvas.style('display','block');
var x_center = (p.windowWidth - w) / 2;
var y_center = (p.windowHeight - h) / 2;
canvas.position(x_center, y_center);
t += .01;
for (var j = 2; x = y = j--;){
for (var i = w; d = p.noise(t - i / 99) * 3, i--; x += Math.cos(d) * 6, y += Math.sin(d) * 6){
j ? i - w / 2 || ( T = p.translate)(-x, -y) : p.push() + T(x + w / 2, y + w / 2) + p.rotate(d + Math.PI / 4) + p.line(-600, 100, 600, 100) + p.pop(i % 100 || p.scale(80));
}
}
}
window.onresize = function() {
// assigns new values for width and height variables
w = window.innerWidth;
h = window.innerHeight;
canvas.size(w,h);
}
}
Is that possible to use async and await? If yes how?
So in my Sketch file, instead of
p5.keyPressed = () => {
...
...
bunch of chaining setTimeout (..., 1000)
}
Can I do,
async p5.keyPressed = () => {
...
...
await delay(1000)
}
What's the right syntax to do this?
Module not found: Can't resolve 'p5'
Module not found: Can't resolve 'p5' in '..\node_modules\react-p5-wrapper\dist'
What am I doing wrong?
Capture webcam video with createCapture() but not found
I tried to capture video with my webcam but react-p5-wrapper not found function createCaptrue(). Or I miss something?
bundle size over 1mb
Hi,
I just imported the react-p5-wrapper into my website and suddenly the bundle increases by 1mb. Is that normal? It can not be that this bundle is that huge after production.
Version: webpack 4.27.1
Recommend Projects
-
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
OpenClaw
Personal AI Assistant
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
-
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
-


