Skip to content

A react-y p5 starter built on nextjs. Largely inspired by @mattdesl's canvas-sketch

Notifications You must be signed in to change notification settings

xanderjl/p5-starter

Repository files navigation

What Is This Project?

FIRST AND FOREMOST, this project is largely based on Matt DesLaurier's canvas-sketch.

This project is an attempt to be an accessible, low barrier to entry sketchbook for generative art. The styling is minimal, and the rest of the opinionated pieces should be largely abstracted away.

Getting Started

First, run the development server:

npm run dev
# or
yarn dev

Open http://localhost:3000 with your browser to see the result.

You can start editing the page by modifying pages/index.tsx. The page auto-updates as you edit the file.

API routes can be accessed on http://localhost:3000/api/hello. This endpoint can be edited in pages/api/hello.ts.

The pages/api directory is mapped to /api/*. Files in this directory are treated as API routes instead of React pages.

Create a New Sketch

This project leverages the power of hygen to do all of the tedious heavy lifting for you. There are two templates to get you started.

Fullscreen:

yarn new:sketch:fullscreen <sketch_name>

# eg
yarn new:sketch:fullscreen mandelbrot-set

Square:

yarn new:sketch:square <sketch_name>

# eg
yarn new:sketch:square archimedean-spiral

Either of these commands will drop a new <sketch_name>.tsx file into ./src/pages/sketches for you.

The flow would look something like

yarn new:sketch:square my-new-sketch
// ./src/pages/sketches/my-new-sketch.tsx
import SketchWrapper from 'components/SketchWrapper'
import { NextPage } from 'next'
import { ColorValue, Draw } from 'types/CustomP5'

const MyNewSketch: NextPage = () => {
  const width: number = 2048
  const height: number = 2048
  const dimensions: number[] = [width, height]
  const padding: number[] = [40]
  const background: ColorValue = [255, 253, 252]

  const draw: Draw = p5 => {}

  return (
    <SketchWrapper
      draw={draw}
      dimensions={dimensions}
      padding={padding}
      background={background}
    />
  )
}

export default MyNewSketch

You can navigate to this sketch by either finding it in the list of sketches on the landing page at http://localhost:3000 or you could navigate to http://localhost:3000/sketches/my-new-sketch

How Do I Work With p5 in This Environment?

You can treat any of your sketch pages as if you were writing a p5 sketch in instance mode.

Setup

Let's assume you wanted to change the default colorMode of this sketch with a setup function. What might that look like?

import SketchWrapper from 'components/SketchWrapper'
import { NextPage } from 'next'
import { ColorValue, Draw, Setup } from 'types/CustomP5'

const MyNewSketch: NextPage = () => {
  const width: number = 2048
  const height: number = 2048
  const dimensions: number[] = [width, height]
  const padding: number[] = [40]
  const background: ColorValue = [255, 253, 252]

  const setup: Setup = p5 => {
    p5.colorMode(p5.HSB)
  }

  const draw: Draw = p5 => {}

  return (
    <SketchWrapper
      setup={setup}
      draw={draw}
      dimensions={dimensions}
      padding={padding}
      background={background}
    />
  )
}

export default MyNewSketch

We define a setup arrow function and perform whatever logic we'd like. We then need to pass that function to the setup prop in the <SketchWrapper /> component. There is a lot going on under the hood of the <SketchWrapper /> that offers you some strong defaults. Maintaining the ratio of your sketch as you resize the window, being able to save sketches with cmd + s or ctrl + s depening on your OS, etc. This functionality won't be overwritten by passing in new props. You'd need to specifically override what these utility functions are doing. To get a feel for what's going on there, you can take a look in ./src/util/defaults.

Note how there's a custom Setup type that offers a nice DX through intellisense. Most common p5 functions have their own custom type definition, but in the event you need to add your own, there's also a P5Function type that you're able to extend to suit your needs.

Draw

Let's draw a circle of points in our new sketch.

import SketchWrapper from 'components/SketchWrapper'
import { NextPage } from 'next'
import { ColorValue, Draw, Setup } from 'types/CustomP5'

const width: number = 2048
const height: number = 2048
const dimensions: number[] = [width, height]
const padding: number[] = [40]
// Change background color to black (in HSB).
const background: ColorValue = [0, 0, 0]

const setup: Setup = p5 => {
  p5.colorMode(p5.HSB)
}

const draw: Draw = p5 => {
  p5.noLoop()
  // Set stroke color to white
  p5.stroke(0, 255, 255)
  p5.strokeWeight(6)

  // create an array with a length of TWO_PI.
  const circleArray = Array.from({ length: p5.TWO_PI * 10.1 })

  // For each point in the array, calculate the cartesian coordinates to draw a point.
  circleArray.forEach((_, i) => {
    const a = i * 0.1
    const r = p5.width / 3
    const x = r * Math.cos(a) + p5.width / 2
    const y = r * Math.sin(a) + p5.height / 2

    p5.point(x, y)
  })
}

const MyNewSketch: NextPage = () => (
  <SketchWrapper
    setup={setup}
    draw={draw}
    dimensions={dimensions}
    padding={padding}
    background={background}
  />
)

export default MyNewSketch

I've done my best to add comment to show what's going on in the draw function, but the important takeaways are this: We are creating an array with the length of TWO_PI to two decimal places (mutliplied by 10.1 to account for a weird rounding error). Within that array, we are using the index of a forEach() loop to generate our angle. We create an arbitrary radius based on the canvas' size, and then convert those polar coordinates to cartesian by using Math.cos() and Math.sin(). Then all we have to do is plot a point with those x and y values to give us our circle of dots!

Learn More

To learn more about Next.js, take a look at the following resources:

Deploy on Vercel

The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.

Check out our Next.js deployment documentation for more details.

About

A react-y p5 starter built on nextjs. Largely inspired by @mattdesl's canvas-sketch

Resources

Stars

Watchers

Forks

Packages

No packages published