p5.jsでサウナの日アニメーションを作る!【スマホ対応インタラクティブ機能付き】
「サウナの日」をテーマにしたp5.jsアニメーションを作りたい? よし、私が最高のコードを教えてあげるわ!でも、ちゃんと理解しなさいよね! ……べ、別に教えたいわけじゃないんだからね!
目次
ツンデレ先生と一緒に学ぶ!p5.jsアニメーション開発
🔥 サウナの雰囲気を再現するアニメーションを作ろう
p5.jsを使って、サウナのストーブから立ち上る蒸気を表現したアニメーションを作るわよ! スマホでも触れると蒸気が増えるインタラクティブ機能もつけるから、しっかりついてきなさい!
👩🏫 GPT先生と生徒のチャット
🧑🎓 「先生!サウナの日をテーマにp5.jsのアニメーションを作りたいです!」
👩🏫 「はぁ?サウナの日?べ、別に興味あるわけじゃないけど、面白そうだから教えてあげるわよ!」
🧑🎓 「じゃあ、サクッと動くやつを作ってください!」
👩🏫 「ちょっと!そんな雑な頼み方しないでよ!……でもまあ、初心者でも分かるように、超分かりやすく教えてあげるんだからね!」
ステップ1:p5.jsの準備
🧑🎓 「まず、何をすればいいんですか?」
👩🏫 「まずはp5.jsのライブラリを読み込むのよ!HTMLに次のコードを追加するだけでOK!」
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.min.js"></script>
🧑🎓 「お、思ったより簡単ですね!」
👩🏫 「ふふん、まあね!でもまだ油断しちゃダメよ!」
ステップ2:キャンバスを作成
🧑🎓 「次はどうします?」
👩🏫 「次に、p5.jsのキャンバスを作るのよ!`setup()`関数を使ってね!」
function setup() {
createCanvas(windowWidth, windowHeight);
smooth();
}
🧑🎓 「なるほど!画面全体にキャンバスが広がる感じですね!」
👩🏫 「そうよ!少しは分かってきたじゃない!」
ステップ3:サウナのストーブと蒸気の描画
🧑🎓 「そろそろサウナっぽくなってくるんですか?」
👩🏫 「もちろんよ!まずはストーブを描いて、そこから蒸気が立ち上るようにするわ!」
function draw() {
background(94, 59, 43);
let stoveWidth = width * 0.2;
let stoveHeight = height * 0.05;
fill(100, 60, 50);
rect(width / 2 - stoveWidth / 2, height - stoveHeight - 20, stoveWidth, stoveHeight, 10);
for (let i = 0; i < 3; i++) {
particles.push(new Particle(width / 2 + random(-20, 20), height - stoveHeight - 20));
}
}
🧑🎓 「わぁ!これでストーブができましたね!」
👩🏫 「でもまだ終わりじゃないわよ!蒸気の動きを作らないとね!」
ステップ4:蒸気のクラスを作成
👩🏫 「蒸気を自然な動きにするために、クラスを作るわよ!」
class Particle {
constructor(x, y) {
this.pos = createVector(x, y);
this.vel = createVector(random(-0.5, 0.5), random(-2.5, -1));
this.lifespan = 255;
this.size = random(10, 20);
}
update() {
this.pos.add(this.vel);
this.lifespan -= 2;
}
show() {
noStroke();
fill(255, this.lifespan);
ellipse(this.pos.x, this.pos.y, this.size);
}
}
🧑🎓 「ふむふむ…これで蒸気が自然に消えていくんですね!」
👩🏫 「そうよ!さて、最後にスマホでも楽しめる機能をつけるわ!」
ステップ5:スマホ対応のインタラクティブ機能を追加
👩🏫 「スマホでタップしたら蒸気が増えるようにするわよ!」
function touchStarted() {
for (let i = 0; i < 10; i++) {
particles.push(new Particle(mouseX, mouseY));
}
return false;
}
function touchMoved() {
for (let i = 0; i < 3; i++) {
particles.push(new Particle(mouseX, mouseY));
}
return false;
}
🧑🎓 「おお!指で触ると蒸気が増えて、楽しくなりますね!」
👩🏫 「ふふん、気に入った?まあ、あなたが喜んでくれるなら…別に嬉しくなんかないんだからね!」
まとめ
今回はp5.jsを使って「サウナの日」にぴったりの蒸気が立ち上るアニメーションを作ったわ! しかもスマホでタップしたら蒸気が増えるインタラクティブ機能付き! あなたもぜひ試してみてね!……別に、楽しんでほしいわけじゃないんだから!
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>サウナの日 - p5.js Animation with Mobile Interaction</title>
<style>
/* Remove default margins and hide scrollbars */
body {
margin: 0;
padding: 0;
overflow: hidden;
background: #5e3d32; /* fallback background color */
}
</style>
</head>
<body>
<!-- Include p5.js library from CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.min.js"></script>
<script>
// Particle class representing a steam particle
class Particle {
constructor(x, y) {
this.pos = createVector(x, y);
// Set an initial random upward velocity with slight horizontal variation
this.vel = createVector(random(-0.5, 0.5), random(-2.5, -1));
// Small upward acceleration to simulate buoyancy
this.acc = createVector(0, -0.01);
// Lifespan controls fading out (starts fully opaque)
this.lifespan = 255;
// Randomize size a bit
this.size = random(10, 20);
}
// Update particle's position and fade its lifespan
update() {
this.vel.add(this.acc);
this.pos.add(this.vel);
this.lifespan -= 2;
}
// Check if the particle has faded completely
isDead() {
return this.lifespan < 0;
}
// Draw the particle as a soft white ellipse with fading transparency
show() {
noStroke();
fill(255, this.lifespan);
ellipse(this.pos.x, this.pos.y, this.size);
}
}
// Array to hold steam particles
let particles = [];
function setup() {
// Create a full-window canvas
createCanvas(windowWidth, windowHeight);
smooth();
}
function draw() {
// Draw a background with a warm, dark wood color (sauna interior)
background(94, 59, 43);
// Draw a sauna stove at the bottom center
let stoveWidth = width * 0.2;
let stoveHeight = height * 0.05;
fill(100, 60, 50);
// Rounded rectangle for a softer look
rect(width / 2 - stoveWidth / 2, height - stoveHeight - 20, stoveWidth, stoveHeight, 10);
// Draw glowing stones on the stove to indicate heat
let stoneCount = 5;
for (let i = 0; i < stoneCount; i++) {
// Distribute stones evenly across the stove
let stoneX = map(i, 0, stoneCount - 1, width / 2 - stoveWidth / 2 + 20, width / 2 + stoveWidth / 2 - 20);
let stoneY = height - stoveHeight - 20;
fill(255, 80, 0, 200); // Red-orange glow
ellipse(stoneX, stoneY, 20);
}
// Define the emission point at the top of the stove
let emissionPoint = createVector(width / 2, height - stoveHeight - 20);
// Emit a few steam particles every frame with a slight horizontal offset
for (let i = 0; i < 3; i++) {
particles.push(new Particle(emissionPoint.x + random(-20, 20), emissionPoint.y));
}
// Update and display each particle; remove if it has faded out
for (let i = particles.length - 1; i >= 0; i--) {
particles[i].update();
particles[i].show();
if (particles[i].isDead()) {
particles.splice(i, 1);
}
}
// Display the title "サウナの日" at the top center
textAlign(CENTER, CENTER);
textSize(48);
fill(255, 200);
text("サウナの日", width / 2, 50);
}
// Add mobile interactivity: spawn extra particles on touch events
function touchStarted() {
// Emit a burst of particles at the touch location when tapped
for (let i = 0; i < 10; i++) {
particles.push(new Particle(mouseX + random(-20,20), mouseY));
}
return false; // Prevent default touch behavior
}
function touchMoved() {
// Continuously emit particles as the finger moves
for (let i = 0; i < 3; i++) {
particles.push(new Particle(mouseX + random(-20,20), mouseY));
}
return false; // Prevent default touch behavior
}
// Ensure the canvas resizes with the browser window
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
</script>
</body>
</html>
コメント