P5.js + Reactのセットアップ

## 前提の話

今年の[Qiita Conference](https://qiita.com/official-campaigns/conference/2024)のサイトでは、[WebGL](https://developer.mozilla.org/ja/docs/Web/API/WebGL_API)を使い背景にアニメーションを施してました。
もともと数学が好きではなく、3Dとかそういったものにも興味はなかったのですが「チーム内でもそういったものをキャッチアップしていこう」という動きもあって、ちょっと触ってみようと思いたった次第です。

## P5.jsとは
QiitaにもP5.jsの記事は沢山あるのですが、あえて初めてP5.jsのことを知った人のために紹介をしておきます。

> p5.j​​s はクリエイティブ コーディング用の JavaScript ライブラリで、アーティスト、デザイナー、教育者、初心者など、誰もがコーディングにアクセスし、包括的に活用できるようにすることに重点を置いています。p5.js は無料かつオープン ソースです。

[P5.jsのwiki](https://github.com/processing/p5.js/wiki)より

ここ数年ではプログラミング初学者、小学生や中学生のプログラミング教材としてP5.jsが使われていることもあるそうです。

https://note.com/ippunkan/n/n11a91e7c2cb3

P5.jsをはじめるだけなら、ブラウザさえあれば[オンラインエディタ](https://editor.p5js.org/)でいきなりコーディングが出来たりします。

## WebGLじゃなくてP5.jsなのはなぜ？
アニメーションの実装が、WebGLよりも敷居が低そうと思ったからです。
いきなりハードルが高いと、分からなくなったら高確率で放り投げてしまうので敷居は低いにこしたことは無いです。

## セットアップ

今回はReactとP5.jsのセットアップをやっていきます。
`create-react-app`が非推奨になり、Next.jsやRemixなどのフレームワークと併用して作成することが推奨されていますが、今回はお試しで使うだけなのでViteとReactで作成していきます。

**実行環境**
- MacOS Sequoia 15.1.1
- Node 22.12.0
- npm 10.9.0

まずはターミナルを立ち上げて作成のコマンドを入力します。

```bash
npm create vite@latest
```
するとどんな名前のプロジェクトにするか聞かれるので任意の名前にします。
ここでは`my-p5js-test`という名前のプロジェクトにします。

```bash
? Project name: › my-p5js-test
```
プロジェクト名を決めたら、今度はどんなフレームワークを使用するか聞かれるので、Reactを選択します。

![スクリーンショット 2024-12-09 0.34.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3443/78933593-948f-5834-a230-ef563a5134fb.png)

するとJavaScriptとTypeScriptのどちらか使用するかを聞かれるので、TypeScriptを選択します。


![スクリーンショット 2024-12-09 0.35.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3443/a702c687-d4e5-3396-24d2-02c31e7f11ee.png)
とても分かりづらい画像ですが一番上が「TypeScript」上から二番目が「TypeScript + SWC」になっています。
ちなみにSWCとはVercel社が作成しているBabelの代替えとなるコンパイラーらしく、Babelよりも20倍早いそうです。

https://zenn.dev/rabbit/articles/957a7e3695e638

これでプロジェクト作成完了です。

```bash
Done. Now run:

  cd my-p5js-test
  npm install
  npm run dev
```
さらに`cd my-p5js-test`で移動し、`npm install`、`npm run dev`の順にコマンドを入力すると以下のようなメッセージが出ます。

```bash
➜  Local:   http://localhost:5173/
➜  Network: use --host to expose
➜  press h + enter to show help
```

ブラウザで`http://localhost:5173/`にアクセスすると初期画面が表示されています。

![Vute + Reactで立ち上げたローカル開発画面のトップページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3443/4bb58251-a484-d845-f33a-2eba1f08e08b.png)


次にP5.jsを使用するパッケージをインストールします。

```bash
npm install p5 @p5-wrapper/react
```

今回は背景をアニメーションしたいので`Background.tsx`というファイルを作ります。
そこで、とりあえず動くかどうかを試してみたいので、[公式のコード](https://github.com/P5-wrapper/react?tab=readme-ov-file#typescript-1)をコピペしてみました。

```Background.tsx
import { ReactP5Wrapper, 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 const Background = () => {
	return <ReactP5Wrapper sketch={sketch} />;
};
```

そして`App.tsx`でimportして表示させてみます。

```App.tsx
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import { Background } from "./background/Background"; // インポート
import "./App.css";

function App() {
	const [count, setCount] = useState(0);

	return (
		<>
			<div>
				<Background /> {/* この位置で表示させてみる　*/}
				<a href='https://vite.dev' target='_blank'>
					<img src={viteLogo} className='logo' alt='Vite logo' />
				</a>
				<a href='https://react.dev' target='_blank'>
					<img src={reactLogo} className='logo react' alt='React logo' />
				</a>
			</div>
			<h1>Vite + React</h1>
			<div className='card'>
				<button onClick={() => setCount((count) => count + 1)}>
					count is {count}
				</button>
				<p>
					Edit <code>src/App.tsx</code> and save to test HMR
				</p>
			</div>
			<p className='read-the-docs'>
				Click on the Vite and React logos to learn more
			</p>
		</>
	);
}

export default App;
```

![スクリーンショット 2024-12-18 0.08.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3443/e918dade-3779-54b8-e77f-f439dac841ab.png)

どうやら表示できているようです。
一応今回はセットアップのみになります。

## 参考

https://p5js.org/

https://note.com/monotein/n/n1604f85d6c73

https://ics.media/entry/210129/

https://zenn.dev/thetalemon/articles/46d4ae2561222c