半澤と申します!
個人的にデザインを調べていた時にp5.jsというアニメーションを作れるJavaScriptのライブラリを見つけたので触ってみた記録を残します。
アプリ作成
ターミナルを起動し、作成するディレクトリに移動して以下のコマンドを入力する。
「sample-app」の部分はプロジェクト名なのでご自由に。設定はよしなに。
yarn create next-app sample-app --typescript
? Would you like to use ESLint with this project? › Yes
? Would you like to use `src/` directory with this project? › Yes
? Would you like to use experimental `app/` directory with this project? … No
? What import alias would you like configured? › @/*
p5.js導入
こちらの記事を参考に導入します。
作成したプロジェクトをVSCordで開き、ターミナルから以下のコマンドを実行する。
yarn add react-p5
個人的にコンポーネントで管理したいのでsrc/components/p5.tsxを作成し、ソースを書いていきます。
関数の簡単な説明をコメントで書いておきます。
src/components/p5.tsx
import dynamic from "next/dynamic";
import p5Types from "p5";
const Sketch = dynamic(import('react-p5'), {
loading: () => null,
ssr: false
})
export const p5 = () => {
// 画像などのロードを行う
const preload = (p5: p5Types) => {
};
// 初期処理
const setup = (p5: p5Types, canvasParentRef: Element) => {
// 背景の大きさ設定
// 画面サイズに合わせるようにしている
p5.createCanvas(p5.windowWidth, p5.windowHeight);
// 背景色設定
p5.background(0);
// オブジェクトの設置
// キャンバス内の中心に100pxの丸を表示する
p5.ellipse(p5.windowWidth / 2, p5.windowHeight / 2, 100)
// オブジェクトの色設定
p5.fill(255, 255 , 0);
};
// 1フレームごとの処理
const draw = (p5: p5Types) => {
};
// コンポーネントのレスポンシブ化
const windowResized = (p5: p5Types) => {
p5.resizeCanvas(p5.windowWidth, p5.windowHeight);
};
return (
<Sketch
preload={preload}
setup={setup}
draw={draw}
windowResized={windowResized}
/>
);
};
色についての引数は…
- 1つの場合:グレースケール 0 が黒で 255 が白
- 2つの場合:グレースケール + 不透明度
- 3つの場合:RGB指定(例:255, 255, 255)
- 4つの場合:RGB + 不透明度
- カラーコードでも指定可能(background(“#000000”))
t5.tsxの表示確認をするので以下のファイルの内容を変更する。
src/pages/index.tsx
import { Inter } from 'next/font/google'
import { p5 } from '@/components/p5'
const inter = Inter({ subsets: ['latin'] })
export default function Home() {
const p5Element = p5();
return (
<>
{p5Element}
</>
)
}
ターミナルで以下のコマンドを入力する。
yarn dev
このように表示されていたらOK!
チュートリアル
調べてみるといろいろ例を公開していただいている。
一つ試してみる。
ソースはこんな感じになりました。
src/components/t5.tsx
import dynamic from "next/dynamic";
import p5Types from "p5";
const Sketch = dynamic(import('react-p5'), {
loading: () => null,
ssr: false
})
export const p5_2 = () => {
// 画像などのロードを行う
const preload = (p5: p5Types) => {
};
// 初期処理
const setup = (p5: p5Types, canvasParentRef: Element) => {
p5.createCanvas(720, 720);
p5.noFill();
p5.background(255);
p5.strokeWeight(2);
p5.stroke(0, 25);
};
// 1フレームごとの処理
const draw = (p5: p5Types) => {
if (p5.mouseIsPressed && p5.mouseButton == p5.LEFT) {
p5.push();
p5.translate(p5.width / 2, p5.height / 2);
var circleResolution = p5.int(p5.map(p5.mouseY + 100, 0, p5.height, 2, 10));
var radius = p5.mouseX - p5.width / 2;
var angle = p5.TAU / circleResolution;
p5.beginShape();
for (var i = 0; i <= circleResolution; i++) {
var x = p5.cos(angle * i) * radius;
var y = p5.sin(angle * i) * radius;
p5.vertex(x, y);
}
p5.endShape();
p5.pop();
}
};
// コンポーネントのレスポンシブ化
const windowResized = (p5: p5Types) => {
p5.resizeCanvas(p5.windowWidth, p5.windowHeight);
};
return (
<Sketch
preload={preload}
setup={setup}
draw={draw}
windowResized={windowResized}
/>
);
};
まとめ
このように色々なアニメーションを作ることができるp5.js君でした。
ですが、ここまで調べておきながら案件で使用されているところを見たことないです。
理由を調べてみましたがはっきりとしてものが出てこなかったですが、jsよりcssとかでアニメーションを実装した方が処理が軽いし学習コストが低いのではないかと憶測しました。
まだあまり調べてませんが、p5.jsで作ったアニメーションをCCapture.jsというものを使えばgifやpng形式で保存できるみたい…
いつかバックエンドの重い処理を走らせている間とかに、ゲームのロード画面みたいに待ち時間が苦じゃないアニメーションを作ってみたいと思います。