コードエディター 本文
<div class="aquarium-container">
<canvas id="aquarium"></canvas>
</div>
カスタムJavaScript
const canvas = document.getElementById('aquarium');
const ctx = canvas.getContext('2d');
let width, height;
const fishes = [];
const bubbles = [];
const FISH_COUNT = 5;
const BUBBLE_COUNT = 8;
function resize() {
width = canvas.width = canvas.parentElement.clientWidth;
height = canvas.height = 100; // 高さを100pxに固定
}
// 魚のクラス
class Fish {
constructor() {
this.x = Math.random() * width;
this.y = Math.random() * height;
this.size = 5; // さらに小さく
this.speedX = (Math.random() - 0.5) * 1.2;
this.speedY = (Math.random() - 0.5) * 0.3;
this.color = `hsl(${Math.random() * 30 + 15}, 100%, 60%)`; // 鮮やかなオレンジ
}
update() {
this.x += this.speedX;
this.y += this.speedY;
if (this.x < 5 || this.x > width - 5) this.speedX *= -1;
if (this.y < 5 || this.y > height - 5) this.speedY *= -1;
}
draw() {
ctx.save();
ctx.translate(this.x, this.y);
if (this.speedX < 0) ctx.scale(-1, 1);
ctx.fillStyle = this.color;
// 胴体
ctx.beginPath();
ctx.ellipse(0, 0, this.size, this.size/2.5, 0, 0, Math.PI * 2);
ctx.fill();
// 尾びれ
ctx.beginPath();
ctx.moveTo(-this.size + 1, 0);
ctx.lineTo(-this.size - 3, -3);
ctx.lineTo(-this.size - 3, 3);
ctx.fill();
ctx.restore();
}
}
// 泡のクラス
class Bubble {
constructor() {
this.init();
}
init() {
this.x = Math.random() * width;
this.y = height + Math.random() * 20;
this.r = Math.random() * 2 + 1;
this.speedY = Math.random() * 0.5 + 0.2;
this.opacity = Math.random() * 0.5;
}
update() {
this.y -= this.speedY;
if (this.y < -10) this.init();
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.strokeStyle = `rgba(255, 255, 255, ${this.opacity})`;
ctx.stroke();
}
}
function setup() {
resize();
for (let i = 0; i < FISH_COUNT; i++) fishes.push(new Fish());
for (let i = 0; i < BUBBLE_COUNT; i++) bubbles.push(new Bubble());
animate();
}
function animate() {
ctx.clearRect(0, 0, width, height);
// 泡の描画
bubbles.forEach(b => { b.update(); b.draw(); });
// 魚の描画
fishes.forEach(f => { f.update(); f.draw(); });
requestAnimationFrame(animate);
}
window.addEventListener('resize', resize);
setup();
カスタムCSS
/* 水槽の設定:高さ100px */
.aquarium-container {
width: 95%;
max-width: 450px;
height: 100px;
border-radius: 8px;
overflow: hidden;
position: relative;
border: 2px solid #555;
/* 背景画像の設定(グラデーションと模様で水槽を表現) */
background:
linear-gradient(rgba(0, 100, 200, 0.4), rgba(0, 50, 100, 0.7)),
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M10 100 Q 20 50 10 0 M30 100 Q 40 60 30 10 M80 100 Q 70 40 80 0" stroke="green" stroke-width="2" fill="none" opacity="0.3"/></svg>');
background-size: cover;
}
canvas { display: block; }
