loading...

Make it Rain 🌧 in HTML Canvas

soorajsnblaze333 profile image Sooraj ・2 min read

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,
}

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

Posted on by:

soorajsnblaze333 profile

Sooraj

@soorajsnblaze333

Simple web developer ❀️ with a Crazy imagination πŸ€ͺ . Does Javascript, Typescript, React, Node, Angular, Svelte & Firebase.

Discussion

markdown guide
 

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.

 

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

 

excelent! please post more canvas content

 

Thanks Mateus πŸ˜ƒ . Definitely will try to make more :)

 

Nice, πŸ˜„, Can you do water spray effect ?

 

Thanks shaijut πŸ˜„ I will sure try :)

 

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/

 

Oh this looks great. Thanks for the info :)