Interactive Aquarium
HTML
<header>
<h1>Interactive Aquarium</h1>
<p class="instructions">Click anywhere in the aquarium to feed the fish!</p>
</header>
<canvas id="aquarium" width="800" height="600"></canvas>
<div class="controls">
<button onclick="addMoreFish()">Add More Fish</button>
<button onclick="clearFood()">Clear All Food</button>
<div class="food-count">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;
background: linear-gradient(to bottom, #001a33, #003366);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
}
header {
text-align: center;
padding: 20px;
color: white;
z-index: 10;
position: relative;
}
h1 {
font-size: 2.5em;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
background: linear-gradient(45deg, #4fc3f7, #29b6f6);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.instructions {
font-size: 1.1em;
opacity: 0.9;
margin-bottom: 20px;
}
#aquarium {
border: 8px solid #1a4d66;
border-radius: 20px;
box-shadow:
0 0 50px rgba(79, 195, 247, 0.5),
inset 0 0 30px rgba(0, 0, 0, 0.3);
cursor: crosshair;
position: relative;
overflow: hidden;
}
.bubble {
position: absolute;
background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.4));
border-radius: 50%;
pointer-events: none;
animation: float-up 8s infinite ease-in-out;
}
@keyframes float-up {
0% {
transform: translateY(100vh) scale(0);
opacity: 0;
}
10% {
opacity: 1;
}
...
JavaScript
const canvas = document.getElementById('aquarium');
const ctx = canvas.getContext('2d');
// Background gradient
const bgGradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
bgGradient.addColorStop(0, '#0a2342');
bgGradient.addColorStop(0.5, '#1a3a52');
bgGradient.addColorStop(1, '#2a4862');
// Decorative elements
const plants = [];
const bubbles = [];
const rocks = [];
// Initialize decorative elements
function initDecorations() {
// Plants
for (let i = 0; i < 5; i++) {
plants.push({
x: Math.random() * canvas.width,
y: canvas.height - 50 - Math.random() * 100,
height: 80 + Math.random() * 120,
sway: Math.random() * Math.PI * 2,
swaySpeed: 0.02 + Math.random() * 0.02
});
}
// Rocks
rocks.push({x: 100, y: canvas.height - 40, width: 150, height: 40});
rocks.push({x: 600, y: canvas.height - 50, width: 180, height: 50});
rocks.push({x: 350, y: canvas.height - 35, width: 120, height: 35});
}
// Fish class
class Fish {
constructor() {
this.x = Math.random() * canvas.width;
this.y = Math.random() * (canvas.height - 200) + 100;
this.size = 20 + Math.random() * 30;
this.speed = 1 + Math.random() * 2;
this.angle = Math.random() * Math.PI * 2;
this.targetAngle = this.angle;
this.color = this.generateColor();
this.tailPhase = Math.random() * Math.PI * 2;
this.tailSpeed = 0.1 + Math.random() * 0.1;
this.eyeOffset = 0;
this.target = null;
this.isHungry = false;
...