DEV Community

Sooraj (PS)
Sooraj (PS)

Posted on

Make it Rain 🌧 in HTML Canvas

Hey guys, I am back with another fun experiment that I created sometime back when I was bored. It was a hot summer day and I hoped so much for it to rain. Since I was so bored, I wanted to make it rain. So I made it rain, not outside, but in my code.

Here is what I achieved


Click Rerun if the rain does not start or if fullscreen is not used.

First of all, this is not a css animation. Only the lightning is a css based animation. I had to use vector math for the rain so that each raindrop falls with increasing velocity. The calculations are all math and physics based.

This was done using HTML canvas and some vanilla javascript.

Steps I followed

  1. Each Raindrop is a class object with its own properties.
  2. When loading the page, 'n' number of raindrop objects are created randomly and pushed to any array.
  3. RequestAnimationFrame was used for animation to optimise the browser animations.
  4. No new raindrop object is added after a raindrop fell to the floor.
  5. I had to do 2 things when a raindrop hit the floor (collision detection).
  6. First is to reset its position, velocity and acceleration. This made it look like never ending rain. This also made sure that the array was not overflowing with values and the objects were reused for better performance.
  7. Second is using its last known position and velocity/acceleration, and create an opposite collection of raindrops that looks like splashes. You know like when a raindrop hits the floor, it loses its momentum and moves in the negative direction until it falls back. Same principle here.
  8. Other than this I also added some presets and global environment, just in case I was going to make other objects interact with the rain
const raintype = {
  drizzle: { count: 30, speed: 0.27 },
  light: { count: 100, speed: 0.3 },
  medium: { count: 250, speed: 0.4 },
  downpour: { count: 500, speed: 0.5 },
  afteshower: { count: 3, speed: 0.4 }
}

var environment = {
  wind: createVector(-0.05, 0),
  raintype: raintype.medium,
}
Enter fullscreen mode Exit fullscreen mode

This was another one of my fun experiments with javascript, math and some imagination. Once in a while, I like to take time off from my official projects and do some imaginative and fun projects like these. And I did learn all those above mentioned concepts from this project.

Hope you like this :)

Codepen Link https://codepen.io/SoorajSnBlz/pen/dyGzKpE

Top comments (13)

Collapse
 
rutesouza profile image
Rute Souza

Loved it! Your code helped me with a project. Thx

Collapse
 
soorajsnblaze333 profile image
Sooraj (PS)

Thank you for the comment. I'm glad it helped you.

Collapse
 
darkain profile image
Vincent Milum Jr

Nice start!

An idea for some advancements: try testing this out on different refresh rate monitors. On my 165Hz display, it starts looking like just curved lines, not "rain" anymore.

I think adding some more random variation to velocities and starting positions can help address this.

Collapse
 
soorajsnblaze333 profile image
Sooraj (PS)

This is a great observation :) Thanks for the heads up. I never knew it would look like curved lines on higher refresh displays. Sure we can just change the environment variables to change the randomness

Collapse
 
mavisidoro profile image
Mateus Ávila 🧀

excelent! please post more canvas content

Collapse
 
soorajsnblaze333 profile image
Sooraj (PS)

Thanks Mateus 😃 . Definitely will try to make more :)

Collapse
 
shaijut profile image
Shaiju T

Nice, 😄, Can you do water spray effect ?

Collapse
 
soorajsnblaze333 profile image
Sooraj (PS)

Thanks shaijut 😄 I will sure try :)

Collapse
 
ahmedshaabanelbehary profile image
Ahmed-Shaaban-Elbehary

cool 😎

Collapse
 
triptych profile image
Andrew Wooldridge

You might find this library useful when you work on something like this in the future - it's perfect for creating lots of instances and recycling them ecsy.io/

Collapse
 
soorajsnblaze333 profile image
Sooraj (PS)

Oh this looks great. Thanks for the info :)

Collapse
 
andrewbaisden profile image
Andrew Baisden

Impressive.

Collapse
 
skvprogrammer profile image
Satyam Kumar Verman

Great 😃😃