Hello, I get an error message saying flow() is not defined when I debug in firebug. I am not sure why this is happening. Here is my code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Image Flow</title>
<script type="text/javascript">
function imageFlow()
{
var R = 0; 
var x1 = .1;
var y1 = .05;
var x2 = .25;
var y2 = .24; 
var x3 = 1.6; 
var y3 = .24; 
var x4 = 300; 
var y4 = 200; 
var x5 = 300; 
var y5 = 200; 
DI = document.images;
DIL = DI.length; 
function flow()
{
    for(var i = 0; i < DIL; i++)
    {
        DIS = DI[i].style;
        DIS.position = 'absolute';
        DIS.left = Math.sin(R * x1+ i * x2 + x3) * x4 + x5;
        DIS.top = Math.cos(R * y1 + i * y2 + y3) * y4 + y5;
    }
    R++; 
}
setInterval("flow()", 5);
void(0);
}
</script>
</head>
<body onload = imageFlow()>
<p><img alt="Nature1" src="img1.jpg" /></p>
<p><img alt="Nature2" src="img2.jpg" /></p>
</body>
</html>

This is because Javascript searches for 'flow()' in the global scope but it so happens that your declaration of flow being present in the function imageFlow is not visible / is not a property of the global object. This can also be attributed to the fact that setTimeout and setInterval always search the global scope.

You can avoid this in many ways, two of which are: Either set this function flow as the property of your function imageFlow or use closures / anonymous functions.

/* Setting the property of imageFlow function */

function imageFlow() {
	var R = 0, x1 = .1, y1 = .05, x2 = .25, y2 = .24, x3 = 1.6, y3 = .24, x4 = 300, y4 = 200, x5 = 300, y5 = 200;
	var DI = document.images, DIL = DI.length;
	var flow = function() {
	    for(var i = 0; i < DIL; i++) {
	        DIS = DI[i].style;
	        DIS.position = 'absolute';
	        DIS.left = Math.sin(R * x1+ i * x2 + x3) * x4 + x5;
	        DIS.top = Math.cos(R * y1 + i * y2 + y3) * y4 + y5;
	    }
	    R++; 
	}
	imageFlow['flow'] = flow;
	setTimeout("imageFlow.flow()", 100);
}
window.onload = imageFlow;
function imageFlow() {
 var R = 0, x1 = .1, y1 = .05, x2 = .25, y2 = .24, x3 = 1.6, y3 = .24, x4 = 300, y4 = 200, x5 = 300, y5 = 200;
 var DI = document.images, DIL = DI.length;
 var flow = function() {
     for(var i = 0; i < DIL; i++) {
         DIS = DI[i].style;
         DIS.position = 'absolute';
         DIS.left = Math.sin(R * x1+ i * x2 + x3) * x4 + x5;
         DIS.top = Math.cos(R * y1 + i * y2 + y3) * y4 + y5;
     }
     R++; 
 }
 setTimeout(function() { flow(); }, 1000);
}
window.onload = imageFlow;

The second one is definitely a better way since calling setInterval() with a string equivalent of javascript (as in the first one) fires of an instance of interpreter to convert the string to actual javascript code, something not recommended since it is pretty expensive performance wise.

Comments
Excellent explanation and example code
This article has been dead for over six months. Start a new discussion instead.