Plugin month - weather

I'm only happy when it rains...

It's time for another interesting but mostly useless plugin - how'd you like to make it rain in your webpage?

Here it is:

Image credit:

Unlike the rest of the plugins I've posted about this month, this one is more of an unfinished experiment. I'd quite like to improve it in future, possibly to include different weather types and more variations. For now it only displays rain, with an optional parameter for wind. Other options include the density of drops, the colour of the drops and their speed. You can also change the width and height of the drops, although they get slightly random variations on the set height to try to simulate depth. The plugin is also partly responsive, using the drop density value to prevent a light shower on desktop turning into a monsoon on mobile.

Details and code are on my github page as usual.

Read on if you're interested in the background and thought behind this plugin.

How it works/worked/doesn't work

This next bit is almost an essay all by itself - how do you make it rain on a webpage? My first idea was to use jQuery to produce hundreds of tiny 'raindrop' elements over an area, then animate them. That proved immediately unviable - the amount of work the browser had to do to continually animate just a hundred drops slowed it to a crawl, violating my rule for webpage effects (if it's a only a visual enhancement, and not a functional enhancement, and it makes the page slow, fix it or drop it).

The second attempt seemed more successful. Instead of continually animating hundreds of tiny elements using JavaScript, I used the plugin to initially create those elements and then animated them using CSS. With this technique I could animate any drop from the top of the parent element to the bottom then back to the start, but it still needed JavaScript to randomly position them at the start, otherwise all it showed was each drop falling together in a perfectly flat line.

The problem with that was that as soon as a drop had to be reset (i.e. it had reached the bottom) all the other drops had to be reset too, meaning that some reached the bottom but some disappeared part way down. I tried an overlap but all it resulted in was a single wave of drops passing into view then disappearing for a moment before falling into view again. A further refinement increased the single wave to three, adding a fade in and out to the animation and an offset so they didn't all fall together. Although this looked much better, even with the most careful timings eventually a gap in the rain was noticeable, and if you stared at it for a while the same pattern of drops would repeat itself - not nearly random enough.

Finally I gave in and went with a HTML5 canvas, which as you can see, works much better, both in terms of performance and also appearance. Subtle effects like variations in falling speed and size of drop are now possible, adding an illusion of depth and making the whole thing appear much more random and natural. It's also easier to make it responsive, as I can easily recalculate the number of drops for different screen widths without having to cycle through elements to add or remove some.

Future work, then? It would be good to have an option for snow, but as the movement of snowflakes can be quite different from rain drops I worry that would almost be a separate plugin. The rain could come and go in bursts, slowing to a few drops and then growing in intensity again, I could add lightning effects and varying wind... but as the plugin doesn't do anything important I'm not hugely motivated right now to devote a lot of time to it.

If you happen to be building a website that desperately needs a configurable weather plugin with some of these options, I'd be interested to hear from you.

JQuery removed

I recently came back to this code and noticed that it's tiny when compressed and doesn't actually need jQuery, so I've rewritten it to be simply a standalone piece of Javascript, which appears to work fine, but now your browser doesn't have to download a separate library to make it work. Hurray for efficiency.


This article is tagged with