Making it snow with Dart

Categories

Dart

Tags

Open Source

After my last example showing you how to create a matrix effect with Dart, I thought it would be cool, to follow up with another example that used the same concepts, but went into slightly more details.

It’s also a bit more complex than the last one, as on this one, we use a few more canvas properties, such as arc to generate our flurries, and beginPath to reset my objects so they’re actual flakes, and not a long rain trace (more on this later).

As per the previous example, I will be using canvas to display my animation.

The final product should look like the following:

Although the animation will be way better than the gif image above.

I start by creating a class that will hold each of my flakes. Not much to explain here. This is only a PODO (Patent Pending) 😉

I then go ahead and initialize some of the variables and constants that will be used by my application. I do it in such way I can experiment with values and get my application to behave in different ways depending on what values I choose.

// Holds all my flakesvarflakes=[];// Maximum number of flakes at a time, and speed in which they fallconstintmaxFlakes=100;//max number of flakesconstintspeed=5;// snowfall speed// Duration of the animationconstthirtyMills=constDuration(milliseconds:30);// Set the screen initial propertiesCanvasRenderingContext2Dctx;varW=window.innerWidth;varH=window.innerHeight;// Randomizer instance variable to be used later on with positions and sizesvarrng=newmath.Random();

Following, I have the brains of my little animation. Everything happens here, from canvas set-up, to flake creation to positioning. I have put together lots of different steps on the same method here. This is almost a <abbr title=’Too long; didn’t read’ rel=’tooltip’>tl;dr</abbr> for code. I don’t want to bore anyone very semantic code. The idea here is to get people going. We all know separation of concerns and good semantics.

voidsnowFall(){// draw background on canvasctx.fillStyle="#000";ctx.fillRect(0,0,W,H);//drawing intitial snowflakes on canvasctx.fillStyle="#fff";// rain ctx.beginPath();for(vari=0;i<maxFlakes;i++){varf=flakes[i];ctx.moveTo(f._x,f._y);ctx.arc(f._x,f._y,f._r,0,math.PI*2,true);}ctx.fill();//moving snow flakesvarangl=0;for(vari=0;i<maxFlakes;i++){angl+=0.1;varf=flakes[i];f._x+=math.sin(angl).abs()+0.1;f._y+=math.cos(angl).abs()*speed;//resetting snowflakes when they are out of frameif(f._x>W||f._x<0||f._y>H){f._x=rng.nextDouble()*W;f._y=-10.0;}}}

Notice we use beginPath every time we call the snowFall() method. This is to make sure the path for each of our flakes get reset, and don’t end up drawing its entire path ton the screen. If we hadn’t used that, we would end up with something like: