ローカル環境でp5.jsでHelloWorld
p5.jsは
とかを使えばオンライン上で編集できるので,動かすのはそれほど困らない
だけどローカル環境でも開発したい
やること
ローカル環境でp5.jsを使ったコンテンツ開発をする
hr.icon
Viteのプロジェクトの作成
code:sh
$ npm create vite@latest react-ts-p5-kitchensink
$ Select a framework: > React
$ Select a variant: > TypeScript + SWC
プロジェクト名はreact-ts-p5-kitchensinkとしたが,これはなんでも良い
hr.icon
生成されたフォルダの中身を確認する
code:sh
.
├── README.md
├── index.html
├── node_modules
├── package-lock.json
├── package.json
├── public
├── src
│ ├── App.css
│ ├── App.tsx
│ ├── assets
│ ├── index.css
│ ├── main.tsx
│ └── vite-env.d.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
hr.icon
まずは動作確認
code:sh
$ npm run dev
https://gyazo.com/c68132bdc91bbf2b1da823db9b49100d
これを変えていく
hr.icon
code:sh
$ npm i p5
$ npm i -D @types/p5
App.tsxを書き換える
code:App.tsx
import { useRef, useEffect } from 'react'
import './App.css'
import p5 from 'p5'
const App = () => {
const sketchRef = useRef<HTMLDivElement | null>(null);
let pos: p5.Vector;
let vec: p5.Vector;
const r: number = 50;
useEffect(() => {
const sketch = (p: p5) => {
p.setup = () => {
p.createCanvas(window.innerWidth, window.innerHeight);
p.frameRate(60);
pos = p.createVector(p.width / 2, p.height / 2);
vec = p.createVector(p.random()*3+2, p.random()*3+2);
};
p.draw = () => {
p.background("#E0E0E0");
pos.x += vec.x;
pos.y += vec.y;
p.noStroke();
p.fill("#507D8B");
p.ellipse(pos.x, pos.y, r*2, r*2);
if (pos.x > p.width - r || pos.x < r) {
vec.x *= -1;
}
if (pos.y > p.height - r || pos.y < r) {
vec.y *= -1;
}
};
};
const myP5 = new p5(sketch);
return () => {
myP5.remove();
};
}, []);
return <div ref={sketchRef}></div>;
};
export default App
実行する
code:sh
$ npm run dev
https://gyazo.com/579f7688d9143b2756b35f36b41681d6
hr.icon
左の方に黒いバーのような領域ができてしまうのでindex.css修正する
デフォルトで書かれている内容は全部消してしまっていいので以下のように修正した
code:index.css
body {
margin: 0;
padding: 0;
}
margin: 0;
padding: 0;
}
https://gyazo.com/87e45bfd9567ab2a3ce20fd55fdd163f
hr.icon
今の状態だとスクロールに反応してしまうのが嫌
https://i.gyazo.com/990ed02324ae5f6bd6f447f7501a4ef9.gif
スクロールイベントをキャンセルさせる
code:App.tsx
...
...
...
const myP5 = new p5(sketch);
const preventDefault = (e: Event) => e.preventDefault();
window.addEventListener('scroll', preventDefault);
return () => {
myP5.remove();
window.removeEventListener('scroll', preventDefault);
};
}, []);
return <div ref={sketchRef}></div>;
};
export default App
index.css側も編集する
code:index.css
body {
overflow: hidden;
margin: 0;
padding: 0;
}
margin: 0;
padding: 0;
}
これでスクロールしても画面は動かなくなったはず
hr.icon
フレームレートを確認したいのでstats.jsを導入する
code:sh
$ npm i stats.js
$ npm i -D @types/stats
App.tsxを書き加える
importする
初期化
draw()の処理を囲む
return()の処理
code:App.tsx
...
import Stats from 'stats.js'
const App = () => {
const sketchRef = useRef<HTMLDivElement | null>(null);
const statsRef = useRef<Stats | null>(null);
...
...
useEffect(() => {
const stats = new Stats();
stats.showPanel(0);
stats.dom.style.position = 'absolute';
stats.dom.style.top = '0px';
stats.dom.style.left = '0px';
document.body.appendChild(stats.dom);
statsRef.current = stats;
...
...
p.draw = () => {
stats.begin();
...
...
...
stats.end();
};
};
...
...
return () => {
myP5.remove();
window.removeEventListener('scroll', preventDefault);
if (statsRef.current) {
document.body.removeChild(statsRef.current.dom);
}
};
}, []);
...
...
https://gyazo.com/d96b70798877b0d9c111cdbb75e85614
左上にFPSが表示されるようになったはず
hr.icon
今のままだとウィンドウサイズを変更した時に対応できない
https://gyazo.com/8dbd2ccc6aca2d3cc4e3eb97986d7386
App.tsxでウィンドウのリサイズに対応させる
code:App.tsx
...
...
...
useEffect(() => {
...
...
const sketch = (p: p5) => {
p.setup = () => {
...
...
...
};
p.draw = () => {
...
...
...
};
p.windowResized = () => {
p.resizeCanvas(window.innerWidth, window.innerHeight);
};
};
...
...
...
setup(), draw()に加えて,windowResized()を追加
https://gyazo.com/974ce0820525bc13162c18a5d120cdc6
ここで公開してる