Aquarium Animation
HTML
<div>
<div class="instructions">Left-click to drop fish food!</div>
<div class="aquarium-container">
<canvas id="aquarium" width="800" height="600"></canvas>
</div>
</div>
CSS
body {
margin: 0;
padding: 20px;
background: linear-gradient(135deg, #001122, #003366);
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.aquarium-container {
position: relative;
border-radius: 20px;
overflow: hidden;
box-shadow: 0 0 50px rgba(0, 150, 255, 0.3),
inset 0 0 50px rgba(0, 100, 200, 0.1);
background: linear-gradient(180deg,
rgba(0, 119, 190, 0.8) 0%,
rgba(0, 50, 100, 0.9) 30%,
rgba(0, 20, 50, 1) 100%);
}
#aquarium {
display: block;
cursor: crosshair;
position: relative;
}
.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%;
pointer-events: none;
opacity: 0.6;
}
.instructions {
color: white;
text-align: center;
margin-bottom: 20px;
font-size: 18px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.food {
position: absolute;
width: 6px;
height: 6px;
background: radial-gradient(circle, #ffaa00, #ff6600);
border-radius: 50%;
pointer-events: none;
box-shadow: 0 0 10px rgba(255, 170, 0, 0.6);
animation: float 3s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
}
@keyframes bubble-rise {
0% {
opacity: 0.6;
...
JavaScript
const canvas = document.getElementById('aquarium');
const ctx = canvas.getContext('2d');
// Aquarium dimensions
const WIDTH = canvas.width;
const HEIGHT = canvas.height;
// Arrays to hold game objects
const fishes = [];
const foods = [];
const bubbles = [];
// Fish colors palette
const fishColors = [
['#FF6B6B', '#FF8E53'], // Orange-red
['#4ECDC4', '#44A08D'], // Teal
['#45B7D1', '#96C93D'], // Blue-green
['#F093FB', '#F5576C'], // Pink-purple
['#FFECD2', '#FCB69F'], // Peach
['#A8EDEA', '#FED6E3'], // Light blue-pink
['#FF9A9E', '#FECFEF'], // Red-pink
['#667EEA', '#764BA2'] // Purple-blue
];
class Fish {
constructor() {
this.size = Math.random() * 30 + 20; // Size between 20-50
this.x = Math.random() * WIDTH;
this.y = Math.random() * HEIGHT;
// Swimming behavior properties
this.baseSpeed = Math.random() * 1 + 0.5;
this.direction = Math.random() * Math.PI * 2;
this.turnSpeed = 0.05;
this.wobble = Math.random() * 0.02 + 0.01;
this.wobbleOffset = Math.random() * Math.PI * 2;
// Color properties
const colorSet = fishColors[Math.floor(Math.random() * fishColors.length)];
this.bodyColor = colorSet[0];
this.finColor = colorSet[1];
// Animation properties
this.tailPhase = Math.random() * Math.PI * 2;
this.mouthOpen = 0;
this.targetFood = null;
this.isChasing = false;
// Swimming area boundaries (avoid edges)
this.margin = 50;
...