Interactive Aquarium
HTML
<div class="aquarium-container">
<div class="bubbles" id="bubbleContainer"></div>
<canvas id="aquariumCanvas" width="900" height="600"></canvas>
<div class="seaweed" style="left: 50px; transform: scale(0.8);"></div>
<div class="seaweed" style="left: 150px; transform: scale(1.2) scaleX(-1);"></div>
<div class="seaweed" style="right: 100px; transform: scale(1);"></div>
<div class="controls">
<h3>🐠 Aquarium Controls</h3>
<p>🖱️ Click to drop food</p>
<p>🐟 Watch them swim!</p>
</div>
<div class="food-counter">
Food pieces: <span id="foodCount">0</span>
</div>
</div>
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
overflow: hidden;
background: linear-gradient(to bottom, #001f3f, #003366);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.aquarium-container {
position: relative;
border-radius: 20px;
overflow: hidden;
box-shadow:
0 20px 40px rgba(0, 0, 0, 0.5),
inset 0 0 50px rgba(255, 255, 255, 0.1);
background: linear-gradient(to bottom,
rgba(0, 119, 190, 0.8) 0%,
rgba(0, 89, 160, 0.9) 20%,
rgba(0, 59, 130, 0.95) 50%,
rgba(0, 39, 100, 1) 100%);
}
canvas {
display: block;
cursor: crosshair;
position: relative;
z-index: 10;
}
.bubbles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 5;
}
.bubble {
position: absolute;
background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.2));
border-radius: 50%;
opacity: 0.6;
animation: float-up linear infinite;
}
@keyframes float-up {
from {
transform: translateY(100vh) scale(0);
opacity: 0;
}
10% {
opacity: 0.6;
}
90% {
opacity: 0.6;
}
to {
transform: translateY(-100px)...
JavaScript
const canvas = document.getElementById('aquariumCanvas');
const ctx = canvas.getContext('2d');
const bubbleContainer = document.getElementById('bubbleContainer');
const foodCountElement = document.getElementById('foodCount');
resizeCanvas();
class Fish {
constructor() {
this.x = Math.random() * canvas.width;
this.y = Math.random() * (canvas.height - 100) + 50;
this.size = Math.random() * 20 + 15;
this.baseSpeed = Math.random() * 1 + 0.5;
this.speed = this.baseSpeed;
this.angle = Math.random() * Math.PI * 2;
this.targetAngle = this.angle;
this.turnSpeed = 0.05;
this.amplitude = Math.random() * 20 + 10;
this.frequency = Math.random() * 0.02 + 0.01;
this.time = Math.random() * Math.PI * 2;
this.hue = Math.random() * 360;
this.saturation = Math.random() * 30 + 70;
this.lightness = Math.random() * 20 + 50;
this.chasingFood = null;
this.mouthOpen = false;
this.tailPhase = 0;
this.lastFoodCheck = 0;
}
update(currentTime) {
this.tailPhase += 0.15;
// Check for new food every few frames
if (currentTime - this.lastFoodCheck > 30) {
this.assignNearestFood();
this.lastFoodCheck = currentTime;
}
if (this.chasingFood && this.chasingFood.active && !this.chasingFood.eaten) {
this.speed = this.baseSpeed * 2.5; // Swim faster when chasing
this.chase();
} else {
this.speed = this.baseSpeed;
...