研究やもらったお仕事でNext.jsを使うことは数年前から多々あったのですが、なかなか書けるネタもなくここまで来てしまいました。
最近記事書いてないなぁというのもあり、ここいらでNext.jsに関する記事も書いてみようかなと思います
やりたいこと
p5.jsをNext.jsとTypeScriptで扱いたい。また他のコンポーネントと組み合わせて使いたい。
手順
まず使うのは react-p5
です。こちらnpm / yarnで入れてあげましょう。
$ yarn add react-p5@1.3.6
なお1.3.6
にバージョン指定していますが、これは既知の未解決バグとして最新バージョンにおいてエラーが出てしまうからです。(こちらのissue参照→2021/02/26追記:アップデートされ最新バージョンでバグが修正されました)
続いて実際にNext.js上でimportするためにも一癖あります。p5.js内でwindow
を使っており、その影響で通常のimportだとエラーが出てしまいます。
これにはNext.jsに用意されているnext/dynamicという機能を用いることで解決できます。具体的なコードはこちらになります
// next/dynamic
import dynamic from 'next/dynamic'
// p5に型付けするためのモジュール
import p5Types from 'p5'
const Sketch = dynamic(import('react-p5'), {
loading: () => <></>,
ssr: false
})
これによって Sketch
という名前でp5.jsが使えるキャンバスを使うことができるようになります。
例えば以下のようなコンポーネントが作成できます。
export const SketchComponent = () => {
const preload = (p5: p5Types) => {
// 画像などのロードを行う
}
const setup = (p5: p5Types, canvasParentRef: Element) => {
p5.createCanvas(p5.windowWidth, p5.windowHeight).parent(canvasParentRef)
// p5でいうsetupの処理を書く
}
const draw = (p5: p5Types) => {
// p5でいうdrawの処理を書く
}
const windowResized = (p5: p5Types) => {
// コンポーネントのレスポンシブ化
p5.resizeCanvas(p5.windowWidth, p5.windowHeight)
}
return (
<Sketch
preload={preload}
setup={setup}
draw={draw}
windowResized={windowResized}
/>
)
}
このように一連の関数はコンポーネントの関数として扱えるため、useStateなどのHooksとの併用も可能です。またp5特有の命令を使う場合は各関数の引数になっているp5を使うことで使えるようになります(p5Types
のおかげでAutoCompleteも使えます。)
Hooksとローカル変数を併用してしまうと、Hooksが更新された段階でローカル変数の状態が関数コンポーネント内の初期値に戻ってしまうのでそこだけ注意しておくといいかもしれません(これは当たり前かもですが...ちなみに変数全てHooksでもちゃんと動きます)
またp5特有の関数はスピードが遅いこともあるのでMath
モジュールの関数で代用できるところは代用するようにしておくとスピード的に向上します。
まとめ
今回はp5.jsをNext.js上で扱うための手順と注意事項をまとめました。なういフロントエンドフレームワークでぜひリッチなメディアアートを楽しんでみてください!