Changed around line 1
+ class Ball {
+ constructor(x, y) {
+ this.x = x;
+ this.y = y;
+ this.vx = (Math.random() - 0.5) * 10;
+ this.vy = (Math.random() - 0.5) * 10;
+ this.radius = Math.random() * 20 + 10;
+ this.color = `hsl(${Math.random() * 360}, 70%, 50%)`;
+ }
+ }
+
+ class BallSimulation {
+ constructor() {
+ this.canvas = document.getElementById('ballCanvas');
+ this.ctx = this.canvas.getContext('2d');
+ this.balls = [];
+ this.gravity = 0.8;
+ this.friction = 0.99;
+ this.bounce = 0.8;
+
+ this.resize();
+ this.setupEventListeners();
+ this.animate();
+ }
+
+ resize() {
+ this.canvas.width = window.innerWidth;
+ this.canvas.height = window.innerHeight;
+ }
+
+ setupEventListeners() {
+ window.addEventListener('resize', () => this.resize());
+
+ document.getElementById('addBall').addEventListener('click', () => {
+ this.addBall(this.canvas.width / 2, this.canvas.height / 3);
+ });
+
+ document.getElementById('reset').addEventListener('click', () => {
+ this.balls = [];
+ });
+
+ document.getElementById('gravity').addEventListener('input', (e) => {
+ this.gravity = parseFloat(e.target.value);
+ });
+
+ this.canvas.addEventListener('click', (e) => {
+ const rect = this.canvas.getBoundingClientRect();
+ const x = e.clientX - rect.left;
+ const y = e.clientY - rect.top;
+ this.addBall(x, y);
+ });
+ }
+
+ addBall(x, y) {
+ this.balls.push(new Ball(x, y));
+ }
+
+ update() {
+ this.balls.forEach(ball => {
+ ball.vy += this.gravity;
+ ball.x += ball.vx;
+ ball.y += ball.vy;
+
+ ball.vx *= this.friction;
+ ball.vy *= this.friction;
+
+ if (ball.x + ball.radius > this.canvas.width) {
+ ball.x = this.canvas.width - ball.radius;
+ ball.vx *= -this.bounce;
+ }
+ if (ball.x - ball.radius < 0) {
+ ball.x = ball.radius;
+ ball.vx *= -this.bounce;
+ }
+ if (ball.y + ball.radius > this.canvas.height) {
+ ball.y = this.canvas.height - ball.radius;
+ ball.vy *= -this.bounce;
+ }
+ if (ball.y - ball.radius < 0) {
+ ball.y = ball.radius;
+ ball.vy *= -this.bounce;
+ }
+ });
+ }
+
+ draw() {
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+
+ this.balls.forEach(ball => {
+ this.ctx.beginPath();
+ this.ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
+ this.ctx.fillStyle = ball.color;
+ this.ctx.fill();
+ this.ctx.closePath();
+
+ // Add shadow
+ this.ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
+ this.ctx.shadowBlur = 10;
+ this.ctx.shadowOffsetX = 5;
+ this.ctx.shadowOffsetY = 5;
+ });
+ }
+
+ animate() {
+ this.update();
+ this.draw();
+ requestAnimationFrame(() => this.animate());
+ }
+ }
+
+ document.addEventListener('DOMContentLoaded', () => {
+ new BallSimulation();
+ });