Skip to content

Instantly share code, notes, and snippets.

@neefrehman
Last active August 12, 2020 14:24
Show Gist options
  • Save neefrehman/c0b25960d1525f03aa0dcc3d1ce26630 to your computer and use it in GitHub Desktop.
Save neefrehman/c0b25960d1525f03aa0dcc3d1ce26630 to your computer and use it in GitHub Desktop.
A react wrapper for p5 sketches. Handles rendering and cleanup.
/* eslint-disable no-new */ /* <- p5 constructor required */
/* eslint-disable new-cap */ /* <- p5 constructor used with lowercase p */
import React, { useRef, useEffect } from "react";
import p5 from "p5";
/**
* A wrapper component for running P5 sketches. Handles rendering and cleanup.
*/
export const P5Wrapper = ({
sketch,
autoResizeToWindow = true,
children
}) => {
const wrapperElement = useRef(null);
useEffect(() => {
const canvas = new p5(sketch, wrapperElement.current);
if (autoResizeToWindow) {
canvas.windowResized = () => {
canvas.resizeCanvas(canvas.windowWidth, canvas.windowHeight);
};
}
return () => canvas.remove();
}, [sketch, autoResizeToWindow]);
return (
<>
<div ref={wrapperElement} />
{children}
</>
);
};
/* eslint-disable no-new */ /* <- p5 constructor required */
/* eslint-disable new-cap */ /* <- p5 constructor used with lowercase p */
import React, { useRef, useEffect } from "react";
import type { ReactNode } from "react";
import p5 from "p5";
interface P5WrapperProps {
/** The p5 sketch function to be run. Must be written in p5's instance mode. */
sketch: (p: p5) => void;
/** If true, the canvas will resize to window whenever the window is resized */
autoResizeToWindow?: boolean;
children?: ReactNode | HTMLElement;
}
/**
* A wrapper component for running P5 sketches. Handles rendering and cleanup.
*/
export const P5Wrapper = ({
sketch,
autoResizeToWindow = true,
children
}: P5WrapperProps) => {
const wrapperElement = useRef<HTMLDivElement>(null);
useEffect(() => {
const canvas = new p5(sketch, wrapperElement.current);
if (autoResizeToWindow) {
canvas.windowResized = () => {
canvas.resizeCanvas(canvas.windowWidth, canvas.windowHeight);
};
}
return () => canvas.remove();
}, [sketch, autoResizeToWindow]);
return (
<>
<div ref={wrapperElement} />
{children}
</>
);
};
import React from "react";
import p5 from "p5";
import { P5Renderer } from "Renderers/P5";
const sketch = (p: p5) => {
let cols: number;
let rows: number;
const scale = 20;
const terrain: number[][] = [];
let flying = 0;
const noisiness = 0.15;
p.setup = () => {
p.createCanvas(p.windowWidth, p.windowHeight, p.WEBGL);
p.background(20);
p.frameRate(24);
p.stroke(255);
p.strokeWeight(0.5);
p.noFill();
cols = p.windowWidth / scale;
rows = p.windowHeight / scale;
};
p.draw = () => {
flying -= noisiness;
let yOff = 0;
for (let x = 0; x < rows; x++) {
terrain[x] = [];
let xOff = flying;
for (let y = 0; y < cols; y++) {
terrain[x][y] = p.map(p.noise(xOff, yOff), 0, 1, -100, 100);
xOff += noisiness;
}
yOff += noisiness;
}
p.background(20);
p.rotateX(p.PI / 3);
p.translate(-p.width / 2, -p.height / 2);
for (let y = 0; y < rows - 1; y++) {
p.beginShape(p.TRIANGLE_STRIP);
for (let x = 0; x < cols; x++) {
p.vertex(x * scale, y * scale, terrain[y][x]);
}
p.endShape();
}
};
};
const S161019 = () => <P5Renderer sketch={sketch} />;
export default S161019;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment