前回の記事の続きになります。
前回の記事はセットアップまでだったので今回は実際にページを作成していきます。
App.tsxの修正
ここから画面いっぱいのアニメーションを作るために編集していきます。
前回のApp.tsx
import { Background } from "./background/Background";
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
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;
デフォルトの要素はいらないので、どんどん削除していきましょう。
修正したApp.tsx
import { Background } from "./background/Background";
function App() {
return (
<>
<Background />
</>
);
}
export default App;
Background.tsxの修正
次に背景ファイルの修正をしていきます。
前回の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} />;
};
一旦はsketch関数の中を空っぽにします。
修正したBackground.tsx
import { ReactP5Wrapper, P5CanvasInstance } from "@p5-wrapper/react";
function sketch(p5: P5CanvasInstance) {
// setupとdrawの中身を削除
p5.setup = () => p5.createCanvas();
p5.draw = () => {
};
}
export const Background = () => {
return <ReactP5Wrapper sketch={sketch} />;
};
今回は雪を降らせるようなアニメーションをしたいので、まず雪の空配列を作ります。
interface Snowflake {
x: number;
y: number;
size: number;
}
const snowflakes: Snowflake[] = [];
背景のアニメーションを画面いっぱいにしたいので、createCanvas
を以下のようにします。
p5.setup = () => {
p5.createCanvas(window.innerWidth, window.innerHeight);
};
今度はdraw
にロジックを書いていきます。
p5.background(20, 30, 50); // 背景を暗くする rgb(20, 30, 50)
p5.fill(255); // 塗りつぶしの色を白にする
p5.noStroke(); // 輪郭線をなしにする
if (p5.frameCount % 5 === 0) {// カウントが始まって5フレーム事
snowflakes.push({
x: p5.random(0, p5.width), // 画面の横ラインでの雪を降らせる位置をランダムで指定
y: 0, // 縦のラインはいらないので0
size: p5.random(2, 5), // 雪のサイズをランダムで指定
});
}
雪の準備が整いましたので、あとは雪を降らせるループを書いていきます。
for (let i = snowflakes.length - 1; i >= 0; i--) {
const snowflake = snowflakes[i];
p5.ellipse(snowflake.x, snowflake.y, snowflake.size);
snowflake.y += snowflake.size * 0.5;
if (snowflake.y > p5.height) {
snowflakes.splice(i, 1);
}
}
そしてCSSで背景を固定させたら完了です。(emotionを使用しました)
雪を降らせる背景がこちらのコードです。
Background.tsx
import { ReactP5Wrapper, P5CanvasInstance } from "@p5-wrapper/react";
interface Snowflake {
x: number;
y: number;
size: number;
}
function sketch(p5: P5CanvasInstance) {
const snowflakes: Snowflake[] = [];
p5.setup = () => {
p5.createCanvas(window.innerWidth, window.innerHeight);
};
p5.draw = () => {
p5.background(20, 30, 50);
p5.fill(255);
p5.noStroke();
if (p5.frameCount % 5 === 0) {
snowflakes.push({
x: p5.random(0, p5.width),
y: 0,
size: p5.random(2, 5),
});
}
for (let i = snowflakes.length - 1; i >= 0; i--) {
const snowflake = snowflakes[i];
p5.ellipse(snowflake.x, snowflake.y, snowflake.size);
snowflake.y += snowflake.size * 0.5;
if (snowflake.y > p5.height) {
snowflakes.splice(i, 1);
}
}
};
}
export const Background = () => {
return <ReactP5Wrapper sketch={sketch} />;
};
画面も雪が降っています。
さらに画面に文字を書いたら完成です。
なんか簡素ですね…
もう少しビジュアルを凝りたかったのですが、今回はここまでにします。
実際に動いているのはこちらになります。
リポジトリはこちら。
メリークリスマ〜ス
参考