1+ // setup canvas
2+
3+ const canvas = document . querySelector ( "canvas" ) ;
4+ const ctx = canvas . getContext ( "2d" ) ;
5+
6+ const width = ( canvas . width = window . innerWidth ) ;
7+ const height = ( canvas . height = window . innerHeight ) ;
8+
9+ // function to generate random number
10+
11+ function random ( min , max ) {
12+ return Math . floor ( Math . random ( ) * ( max - min + 1 ) ) + min ;
13+ }
14+
15+ // function to generate random color
16+
17+ function randomRGB ( ) {
18+ return `rgb(${ random ( 0 , 255 ) } ,${ random ( 0 , 255 ) } ,${ random ( 0 , 255 ) } )` ;
19+ }
20+
21+ class Ball {
22+ constructor ( x , y , velX , velY , color , size ) {
23+ this . x = x ;
24+ this . y = y ;
25+ this . velX = velX ;
26+ this . velY = velY ;
27+ this . color = color ;
28+ this . size = size ;
29+ }
30+
31+ draw ( ) {
32+ ctx . beginPath ( ) ;
33+ ctx . fillStyle = this . color ;
34+ ctx . arc ( this . x , this . y , this . size , 0 , 2 * Math . PI ) ;
35+ ctx . fill ( ) ;
36+ }
37+
38+ update ( ) {
39+ if ( this . x + this . size >= width ) {
40+ this . velX = - this . velX ;
41+ }
42+
43+ if ( this . x - this . size <= 0 ) {
44+ this . velX = - this . velX ;
45+ }
46+
47+ if ( this . y + this . size >= height ) {
48+ this . velY = - this . velY ;
49+ }
50+
51+ if ( this . y - this . size <= 0 ) {
52+ this . velY = - this . velY ;
53+ }
54+
55+ this . x += this . velX ;
56+ this . y += this . velY ;
57+ }
58+
59+ collisionDetect ( ) {
60+ for ( const ball of balls ) {
61+ if ( this !== ball ) {
62+ const dx = this . x - ball . x ;
63+ const dy = this . y - ball . y ;
64+ const distance = Math . sqrt ( dx * dx + dy * dy ) ;
65+
66+ if ( distance < this . size + ball . size ) {
67+ // ball.color = this.color = randomRGB();
68+ const tempVelX = this . velX ;
69+ const tempVelY = this . velY ;
70+ this . velX = ball . velX ;
71+ this . velY = ball . velY ;
72+ ball . velX = tempVelX ;
73+ ball . velY = tempVelY ;
74+ }
75+ }
76+ }
77+ }
78+ }
79+
80+ function loop ( ) {
81+ ctx . fillStyle = "rgb(0 0 0 / 25%)" ;
82+ ctx . fillRect ( 0 , 0 , width , height ) ;
83+
84+ for ( const ball of balls ) {
85+ ball . draw ( ) ;
86+ ball . update ( ) ;
87+ ball . collisionDetect ( ) ;
88+ }
89+
90+ requestAnimationFrame ( loop ) ;
91+ }
92+
93+ const balls = [ ] ;
94+
95+ while ( balls . length < 25 ) {
96+ const size = random ( 10 , 20 ) ;
97+ const ball = new Ball (
98+ // ball position always drawn at least one ball width
99+ // away from the edge of the canvas, to avoid drawing errors
100+ random ( 0 + size , width - size ) ,
101+ random ( 0 + size , height - size ) ,
102+ random ( - 7 , 7 ) ,
103+ random ( - 7 , 7 ) ,
104+ randomRGB ( ) ,
105+ size ,
106+ ) ;
107+
108+ balls . push ( ball ) ;
109+ }
110+
111+ loop ( ) ;
0 commit comments