Exploring Web1.0 kitsch – YUI snowflakes

September 24th, 2006. Tagged: Fun, JavaScript, kitsch, Web1.0, yui

Kitsch

So what's "kitsch"? Well, something that may look like an art, but is usually a thing of a bad taste, over-ornamented, glittering, too colorful, well, something a bit ugly, but liked by a lot of people. It's sometimes questionable what is kitsch and what is a really valuable piece of art, but anything arty is always a bit questionable, isn't it? More about kitsch on Wikipedia.

Web 1.0 kitsch

Here I don't mean to say that anything that is not web 2.0 is ugly, in fact I cannot say that everything that is not web 2.0 is (bad) web 1.0, because there's never a clear difference. Only because you don't have a tag cloud on your site, that doesn't mean your site is old and second best. There are kitschy web2.0 sites, of course, but here I'm thinking about those Web1.0 "effects", things that are hopefully in the past, we've all seen it, it's the rotating 3D @-signs, the animated gifs, the status bar animations, the things that follow your cursor and, of course, the ever so cool, snowflakes flying around the page.

Motivation

My 3-year-old daughter loves to browse with me, asking me to bring up images of Cinderella, Snow White and other favorites. Having no idea where to find them, I do an image search and then visit the sites that come up, hoping for the best. (BTW, that's not always safe, try "barbie") Most of the sites I get are kind of old, web 1.0. style, and one of them had these hearts flying around the screen. My daughter loved them. So I questioned myself how hard it would be to do something similar with all those new cool JS libraries we have today. I tried the YUI and it turned out it is easy, I believe I was able to do the snowflakes within an hour, most of that time spent on figuring out the "mathematical model" of what I was trying to do.

Not ideal

I'm the first to admit the solution is not ideal, for example my flakes are not of random size in IE (my fault) and the whole animation has little breaks every second or so in Firefox. I guess for the seconds bug it's either that YUI is not the best tool for the job or I'm using it the wrong way. But hey, this is a one-hour project. So let me tell you what I did.

The math

What I decided to do is have my snowflakes appearing on random place from top, left or right, and then disappearing at a random place on the left, right or bottom. Also to have a max of 20 flakes at any time, it's bad enough to have 20 to load you processor, more is just crazy. Then I have 4 random points on the screen for each flake that serve as control points when the flake is doing its curve.

Implementation

Using DOM I create a div that contains an asterisk, this is my snowflake. Then I'm using the Motion along the curve available from YUI in order to animate this div. This motion takes a start point, an end point and some control points, in my case 4. First thing to figure out is how much space we have on the screen. YUI helps with this:

max_x: YAHOO.util.Dom.getViewportWidth() - 20,
max_y: YAHOO.util.Dom.getViewportHeight() - 20,

Then the 4 control points are easy, just 4 random points:

var control = [];
for (i = 0; i < 4; i++) {
    control[i] = [
    Math.floor(Math.random() * this.max_x),
    Math.floor(Math.random() * this.max_y)
    ];
}

The hardest part was the start and end points. As I said, I decided to have start points from either top, left or right, so that gives me an array of three random points:

var start_points = [
    [Math.floor(Math.random() * this.max_x), 0],
    [0, Math.floor(Math.random() * this.max_y)],
    [this.max_x, Math.floor(Math.random() * this.max_y)]
];

First is the top where on the Y-axis I have always 0 and a random value for X, from 0 to max_x. The left is defined as X = 0 and Y is random from 0 to max_y, the right is X = max_x and Y is again random from 0 to max_y.

For the end points it's similar, only there instead of top of the screen I have the bottom. For the bottom Y is max_y and X is random.

var end_points = [
    [0, Math.floor(Math.random() * this.max_y)],
    [this.max_x, Math.floor(Math.random() * this.max_y)],
    [Math.floor(Math.random() * this.max_x), this.max_y]
];

Then I pick a random value from each of the two arrays

var this_start_index = Math.floor(Math.random() * 3);
var this_end_index   = Math.floor(Math.random() * 3);
var this_start = start_points[this_start_index];
var this_end   = end_points[this_end_index];

Once I have start/end and control points, I'm ready to create the new flake div, where the size of the flake and the DIV id are random:

// size of the flake
var flake_size = 10 + Math.floor(Math.random() * 20);
 
// random ID of the flake
var flake_id = "flake" + 99 + Math.floor(Math.random() * 99999)
 
// create the markup for the flake (using html2dom.com)
var html2dom_root = document.body;
html2dom_root_1_div = document.createElement("div");
html2dom_root_1_div.setAttribute("id", flake_id);
html2dom_root_1_div.setAttribute("style", "width: 5px; font-size: " + flake_size + "px");
html2dom_root_1_div_1_text = document.createTextNode("*");
html2dom_root_1_div.appendChild(html2dom_root_1_div_1_text);
html2dom_root.appendChild(html2dom_root_1_div);

Now I'm ready to create and setup the YUI animation (motion) instance:

// animation attributes
var attributes = {
   points: {
      to: this_end,
      from: this_start,
      by: [10, 10],
      control: control
   }
};
 
// setup animation/motion object
var myAnim = new YAHOO.util.Motion(flake_id, attributes);
// no easing
myAnim.method = YAHOO.util.Easing.easeNone;
// random duration
myAnim.duration = 20 + Math.floor(Math.random() * 20);
// on completion remove the flake and make more
myAnim.onComplete.subscribe(this.removeElement);
myAnim.onComplete.subscribe(this.make_flakes);
// go!
myAnim.animate();

The two functions that are "subscribed" on animation completion are responsible for removing the current flake div and for creating another set of flakes. The set of flakes generated is using the logic - generate a random number of new flakes (min 1, max 5) unless you've hit the upper limit of 20.

Demo

Here's the demo where you can see the whole script, I kept it in the HEAD part of the demo page.

Tell your friends about this post on Facebook and Twitter

Sorry, comments disabled and hidden due to excessive spam.

Meanwhile, hit me up on twitter @stoyanstefanov