HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

JavaScript "snow" animation

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
javascriptanimationsnow

Problem

I have worked for a few hours and this is the result:



`$(document).ready(function(){
var canvas = $("#snow-collision")[0];
var stats = new Stats();
stats.setMode(1); // 0: fps, 1: ms
var debug = $("#debug");
var pi = Math.PI;
var hpi = pi / 2;
var tpi = hpi * 3;
// align top-left
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';

document.body.appendChild( stats.domElement );

var ctx = canvas.getContext("2d");
var width = canvas.width = $(window).width(),
height = canvas.height = $(window).height();

var snow_canvas = $("#flake-creator")[0],
snow_ctx = snow_canvas.getContext("2d");

$(window).resize(function(){
width = canvas.width = $(window).width();
height = canvas.height = $(window).height();
});

var isClicking = false;
$(document).on("mousedown mouseup", function(e){
isClicking = e.type == "mousedown";
});

var xMouse = null,
yMouse = null;

$(document).mousemove(function(e){
xMouse = e.pageX;
yMouse = e.pageY;
});

var time = 0;
var snowFlakes = [];
var pi = Math.PI;
var windForce = 1;

setInterval(function(){
stats.begin();
time++;

var lSnow = snowFlakes.length;
if(lSnow 90 && md hpi && di = height)
{
snow.CordY = -sSnow;
snow.CordX = RandomRange(sSnow, width - sSnow);
}
else if(xSnow > -dsSnow && xSnow -dsSnow && ySnow 0) xForce = this.ForceX -= 0.1;
else if(xForce 0) spDist /= spN;
else
{
spDist = (spY - spYY)/spN;
spY = spYY;
spYY = spY;
}
var r2 = Math.random() * r, // shorter than main
spY2 = Math.random() * r2, // y of spark
spW2 = Math.random() * spark, // width of spark
spH2 = RandomRange(-spark, spark * 2), // height of spark
spShort = RandomRange(0, 6); // 1 in 6 chance of shorts not showing

snow_ctx.tran

Solution

That is an awesome animation! From a technical viewpoint, I find it neat how you render the flakes into a PNG represented by a data URI.

Realism

A lot of the snowflakes look quite nice. But I see some square, pentagonal and heptagonal snowflakes! What kind of chemicals are you using? Is that even mathematically possible? Is some atmospheric condition causing water to form quasi-crystals?

The repulsive force pushes aside snowflakes that were originally within 100 pixels of the cursor. The flakes that are thus selected for repulsion continue to fly away with sideways momentum, even though other at that radius continue to fall unaffected. I would expect viscous forces to dominate over inertial forces (a "low Reynolds number" condition). (In programming terms, each flake should act as if it were "stateless", and shouldn't store xForce.)

Implementation

The vast majority of the flakes are falling straight down with constant vertical velocity. Since there are only 18 possible discrete values of Gravity, you could assign flakes to one of 18 divs, each div acting as a continuously scrolling layer. Then, within each layer, you only have to move the flakes that are close enough to the cursor to be affected by the simulated wind.

Functions should have lowerCase names by convention. Names such as Direction look like constructors.

The Direction() function would be more elegant without the pi +. Just use Math.atan() more strategically and write return Math.atan2(y0 - y1, x0 - x1);.

Context

StackExchange Code Review Q#74651, answer score: 6

Revisions (0)

No revisions yet.