WmMead

Project 04

The vi­sual re­sults of this pro­ject are slightly dif­fer­ent from the pre­vi­ous ones, as boxes fade in and out, in­stead of just ap­pear and dis­ap­pear. Also, they all be­come fully opaque, rather than have ran­dom trans­parency. The pro­gram­ming for this pro­ject, how­ever, takes a large leap for­ward. I added two func­tions, one for fad­ing el­e­ments in and one for fad­ing el­e­ments out. I also made big changes to the cre­ate­Box() func­tion in order to get these re­sults.

It is significant to point out that the previous projects were not actually recursive. They were only using setInterval to repeat indefinitely. This project uses two recursive functions to handle the random addition and removal of elements to the page. The recursion is necessary to handle the timing of these two functions so that the program can work its way through each state (adding elements and removing elements) properly.

Code Snippets for 04

For 04, I needed to set the initial opacity of elements added to the DOM to zero, and then fade them in. To do this, I updated the CSS at the top of the file.
Updated CSS
div { 
	position:absolute; 
	opacity:0;
}
In order to fade elements in and out, I had to make some fairly significant changes to the createBox() function, including making it fully recursive for the first time. Instead of using setInterval, I am using setTimeout on line 3. Then on line 27, instead of a simple loop to remove elements, you will see an if statement that checks the number of elements on the screen against the randomly chosen maximum number. If there are too many I enter a recursive fade function that fades the extra boxes out. I also added a function to fade boxes in called unfade() which you can see runs on line 21.
Recursive createBox() function
function createBox()
{	
	setTimeout( function(){
		var box = document.createElement("div");
		var boxWidth = getRandomInt(10, windowWidth);
		var boxHeight = getRandomInt(10, windowHeight);
	
		box.style.width = boxWidth + "px";
		box.style.height = boxHeight + "px";
		
		box.style.webkitTransform = 'rotate('+getRandomInt(-360, 360)+'deg)'; 
		box.style.mozTransform = 'rotate('+getRandomInt(-360, 360)+'deg)';
		box.style.transform = 'rotate('+getRandomInt(-360, 360)+'deg)'; 
		
		box.style.top = getRandomInt(-boxHeight, windowHeight) + "px";
		box.style.left = getRandomInt(-boxWidth, windowWidth) + "px";
		
		box.style.backgroundColor = colors[getRandomInt(0, 4)];
		
		//Fade the element in and add it to the DOM
		unfade(box);
		document.getElementById("page").appendChild(box);
		
		var boxMax = getRandomInt(1, 75);
		
		// replace simple loop with if statement and recusive fade program...
		if( container.children.length > boxMax )
		{
			var counter = (container.children.length - boxMax)-1;
			// Enter fade out process..
			fade(container.children[(counter)], counter);
		}
		else
		{
			// Recursive call to createBox, to add another box...
			createBox();	
		}
	}, 1500 );
}
The unfade() function fades elements in as they are added to the page. I set an initial opacity of 0.05 and then run a timer which gets cleared when the element gets to full 100% opacity. The setInterval will run every 50 milliseconds adding 0.05 to the opacity each time, basically it runs 20 times, giving each element 20 steps from transparent to fully opaque.
Fade elements in...
function unfade(element) {
    var op = 0.05;
    var timer = setInterval(function () {
        if (op >= 1){
            clearInterval(timer);
        }
        element.style.opacity = op;
		
		// Expresses values from 0-100 instead of 0-1...
        element.style.filter = 'alpha(opacity=' + op * 100 + ")";
        op += op * 0.05;
    }, 50);
}
The fade function takes and element and a counter. The counter is the number of boxes I want to fade out determined randomly in the createBox function above on line x. This function takes one element at a time, sets the opacity at 1 then subtracts 0.05 from that opacity. It does this every 50 milliseconds to the same element until its opacity hits 0.05 or less. At that point the timer for that element is cleared, the element is removed from the page, and the program checks to see if there is another element to fade out, if so, fade() is called recursively on that element (on line 12), when all the elements have been faded out, createBox() is called (on line 17) and we enter back into the main function.
Fade elements out...
function fade(element, counter) {
    var op = 1;  // initial opacity
	var countDown = counter;
    var timer = setInterval(function () {
        if (op <= 0.05){
            clearInterval(timer);
			container.removeChild(container.children[countDown]);
            countDown--;
			if( countDown > 0 )
			{
				// Recursive call to fade function...
				fade(container.children[countDown], countDown);
			}
			else
			{
				// Recursive call to createBox, to get back into the main function...
				createBox();
			}
        }
        element.style.opacity = op;
        element.style.filter = 'alpha(opacity=' + op * 100 + ")";
        op -= op * 0.05;
    }, 50);
}
Below, I have cleared a lot of the code out of the functions and put in comments to describe what is going on. It is important to understand how the createBox() and fade() recursive functions work together. Based on random conditions, the addition or removal of elements on the screen is getting passed back and forth between these two functions.
Simplified functions
function createBox()
{	
	setTimeout( function(){
		
		// Create the box and styling...
		
		// Fade the box in..
		unfade(box);
		
		// Set the maximum number of elements randomly...
		var boxMax = getRandomInt(1, 75);
		
		// If there are more elements than that random number
		if( container.children.length > boxMax )
		{
			// fade out all the boxes greater than the boxMax number..
			fade(container.children[(counter)], counter);
		}
		else
		{
			// Recursive call to createBox, to add another box...
			createBox();
		}
	}, 1500 );
}

function fade(element, counter) {
   
    var timer = setInterval(function () {
		
		// Fade the first element out...
        if (op <= 0.05){
            
			// If the element is completely faded out, decrement the counter 
			if( countDown > 0 )
			{
				// If there are still elements to fade out, get the next one and keep going..
				fade(container.children[countDown], countDown);
			}
			else
			{
				// If there are no more elements to fade out, enter back into the main function...
				createBox();
			}
        }
        
    }, 50);
}