Zhyohzhy Zhyohzhy - 1 year ago 78
Javascript Question

Animating an image to create rain effect

I’m trying to write a simple enough animation with javascript using HTML5 canvas. It’s an image of rain drops that I want to animate seamlessly. This is the image:


This is how I'm currently animating it:

function Background() {
this.x = 0, this.y = 0, this.w = bg.width, this.h = bg.height;
this.render = function() {
ctx.drawImage(bg, 0, this.y++);
if (this.y <= -199) { //If image moves out of canvas, reset position to 0
this.y = 0;

I’m facing two issues though.

  • I can’t get the image to loop at all. It just falls down the one time, I need to have this on a loop so it’ll continue again when it starts to leave the canvas.

  • Once I know how to properly loop it, there is the issue that the rain isn’t suppose to fall down exactly vertically. It needs to fall down diagonally as the raindrops in the image suggest.

This is where it stops to be a simple enough animation.

Here’s my fiddle, it includes all my code. Thanks a lot.

PS: I’ll take any help with either Javascript or CSS I can get. But I do need the rain effect to be using the image only! I can’t accept anything else unfortunately.

Answer Source

I'd recommend splitting out your loop into an animation loop that calls update() and draw() separately. Update your state in update() and then render that state in draw().

Something like this (bit ragged, but you can perhaps make it better :) ):

var lastTick = 0;
var position = { x:0, y:0 };
var bg = document.getElementById('bg');
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

function update(gameTime) {
	position.x += (70 * gameTime.diff / 1000);
	position.y += (110 * gameTime.diff / 1000);
	if (position.x > canvas.width) {
		position.x = 0;

	if (position.y > canvas.height) {
		position.y = 0;

function draw(gameTime) {
	ctx.clearRect(0, 0, canvas.width, canvas.height);
	ctx.drawImage(bg, position.x, position.y, canvas.width, canvas.height);
	ctx.drawImage(bg, position.x - canvas.width, position.y, canvas.width, canvas.height);
	ctx.drawImage(bg, position.x, position.y - canvas.height, canvas.width, canvas.height);
	ctx.drawImage(bg, position.x - canvas.width, position.y - canvas.height, canvas.width, canvas.height);

function loop(tick) {
	var diff = tick - lastTick;
	var gameTime = { tick:tick, diff:diff };
	lastTick = tick;

<meta charset="UTF-8">
	canvas {
<img id="bg" src="https://s31.postimg.org/475z12nyj/raindrops.png" style="display:none;">
<canvas id="canvas"><h1>Canvas not supported</h1></canvas>