Variable Analysis

Fundamental Variables

There are a few variables that are defined near the beginning and used throughout the code, so let’s start with how those work.

effect_size = 400;

This is simply a constant which controls the size of the effect. It is mostly used to control the vertical size of the effect, and is also used to control the size of the “burst” part of the effect.

timing_variation = (time + Math.cos(i)) % 2;

This is quite an interesting value that adds some variation between when each raindrop falls and bursts. I need to break this down further to illustrate how this value actually changes over time.

By using just time % 2 , we get a value which will cycle over time from 0 to 2. The modulo ( % ) operator gives the remainder after dividing, which will always keep the value below the second number.

By adding Math.cos(i) to the inner part of this variable, we achieve a little bit of a different offset for each raindrop. We can see how this variation contributes to the way the rain falls by removing it.

The raindrops without any timing variation (source)

Not a very convincing effect without that variation. This lets us see a little bit of how this value is used, because we can now see where the variation is gone. All of the rain now falls at the same time and burst at the same place now.

timing_variation starts out negative at the beginning of the effect because of Math.cos(i) , but the negative effect is cancelled out permanently when time becomes equal to 1. This causes the slight delay at the beginning of the original animation, which is a nice effect.

burst_trigger = ~~timing_variation;

This value controls when the raindrops actually burst. Let’s look at how.

If you’re not familiar with it, the ~ operator flips all of the bits in a value. So, if you use it twice, it flips any integer back to its original value. If you use any decimal values, it will remove the decimal part of the number and turn it into an integer, which is special Javascript behaviour. The same effect can be achieved by using Math.ceil for negative values or Math.floor for positive values, but this is a clever way to reduce the number of characters used on Dwitter.

Since timing_variation effectively cycles between 0 and 2 non-inclusive, burst trigger will flip suddenly from 0 to 1. When the trigger is 1, the burst will be in effect. Since there is a little variation for each raindrop, each drop will burst at a different time.

With this knowledge, we can get more insight about how the effect works by looking at how it looks when the rain is always falling.

The raindrops stuck in falling mode (source)

As you can see, the drops actually get smaller before they get larger again, which can be hard to see in the original effect as they burst as soon as they get too small.

We can also see how it looks when the rain is always bursting.

The raindrops stuck in bursting mode (source)

Here, you can actually see that if the effect were to go along long enough, the bursts would cycle between large and small because of the use of sinusoidal functions. You can also see that, between the falling and burst phases, the raindrops completely stop.

drop_size = timing_variation * effect_size - effect_size;

This value controls the size of each drop, both when it is falling and when it is bursting.

The timing variation here gives each drop a slightly different size and causes the drop to change in size over time. The drop size is multiplied by the effect size, which makes it large enough to have a noticeable effect. The effect size is also subtracted, which is what causes the drop to get smaller until it bursts, at which point it gets larger. This is because the drop size goes from negative in the falling phase to positive in the burst phase.

If we change this value, we can see what it would look like if we made the drop size constant throughout the effect.

The raindrops with constant sizes (source)

You can now see clearly what exactly the timing variation adds to the size of each raindrop by comparing it with the original effect.

Horizontal Variables

Now that we know how the basic variables work, let’s look at the values that make up the horizontal position of the drops.

x_distribution = canvas.width * Math.cos(i * i);

This value controls how the drops are spread out horizontally across the canvas. The drops will be distributed across the canvas width in a pattern that, while trigonometric, appears pseudo-random because of how multiplying i by itself causes the pattern to wrap around.

Let’s see how it looks if we do not multiply i by itself.

The raindrops with a clearer horizontal distribution (source)

By removing the pseudo-random distribution, now you can see how each raindrop compares to the next sequential raindrop. However, we can go a step further and remove any horizontal distribution at all by making every raindrop fall in the middle of the canvas.

The raindrops all falling in the middle of the canvas (source)

This makes the effect take on a whole new shape. It actually looks like it could use a whole new analysis. However, if we just remove the timing variation like we did before, we can see that the new shape is just caused by the sinusoidal timing variation.

The raindrops falling in the middle without any timing variation (source)

Now, without any timing or horizontal variation between raindrops, we can pretty clearly see that each raindrop is falling and spreading out in the same way.

x_burst_shape = Math.cos(j);

This, quite simply, gives each burst the circular shape on the horizontal axis by using the Math.cos function. The j value is used, so the position changes for each particle.

By changing this variable, we can change the horizontal shape of each burst. For instance, we can multiply j by itself with Math.cos(j*j) . This uses the same pseudo-random pattern as the horizontal distribution ( Math.cos(i*i) ), so the bursts take on a much more noisier pattern.

The raindrops with a noisy horizontal shape (source)

Vertical Variables

y_position = (

burst_trigger ? effect_size : timing_variation * effect_size

);

This variable simply determines the vertical position of the drops.

When the burst effect is active, the drops freeze in place at the predetermined height. When the effect is not active and timing_varation is less than 1, they will move at a multiple of the predetermined height.

Since the burst effect becomes active when timing_variation becomes 1, the drops freeze exactly in place.

Knowing what this does, we can now make the raindrops go up.

The raindrops falling up (source)

This is achieved by making the variable negative and adding 3 * effect_size .

y_variation = Math.cos(i) * Math.cos(i) + 2;

This adds a little variation to the vertical position of each raindrop.

By multiplying Math.cos(i) by itself, the value will always be positive, so the raindrops won’t burst too high. It will also cause a slightly different pattern than other variables used for variation.

The value of 2 here is simply a constant used to make sure all drops don’t fall too low or too high.

We can now see what it would look like if all of the raindrops fell with the same vertical variation.

The raindrops all bursting in the center of the canvas (source)

This shows all raindrops falling at a height of 2.

We can now remove all horizontal randomness, timing variation, and vertical position variation.

The raindrops all bursting in the center at the same time, evenly spread (source)

This can give us another clear picture of how the effect works.

y_drop_shape = Math.sin(j) / 4;

This variable, like the x_burst_shape , gives the burst its circular pattern. Unlike x_burst_shape , it also contributes to the shape of the drop while it is falling, causing it to get shorter as it falls.

The timing of the effect causes the drop to burst just as this vertical shape variable reaches 0, meaning that the burst will be triggered exactly when the raindrop becomes flat. This gives for a very nice transition.

This shape variable uses Math.sin , whereas the horizontal burst shape variable uses Math.cos . This is what causes the circular shape.

Finally, the constant 4 is used here to make the burst shorter than it is long, creating the perspective effect.

If we didn’t shorten the raindrop, this is what it would look like.

The raindrops without vertical squishing (source)

This is achieved by changing 4 to 1.