Moving dots on a line.

No matter where the line is, the dots will go from start to finish. Change the startPoint/endPoint variables to see different results.

HTML

<canvas id="myCanvas" width="600" height="600"><p>Your primitive, sucky browser does not support canvas.</p></canvas>

CSS

canvas {
	display: block;
	margin:20px auto 0;
	max-width: 100%;
	background:#000000;
}

JavaScript

(function(){
	/* code */
	var theCanvas = document.getElementById('myCanvas'),
		context = theCanvas.getContext('2d'),
		spaceBetween = 20,
		startPoint = {x:theCanvas.width/2,y:50},
		midPoint = {},
		endPoint = {x:theCanvas.width/2,y:550},
		radius = 4,
		increment = 0,
        sineIncrement = 0;


	window.requestAnimFrame = (function(){
        return	window.requestAnimationFrame		||
            window.webkitRequestAnimationFrame	||
            window.mozRequestAnimationFrame		||
            window.oRequestAnimationFrame		||
            window.msRequestAnimationFrame		||
            function( callback ){
                window.setTimeout(callback, 1000 / 60);
            };
	})();


	(function animloop(){
		requestAnimFrame(animloop);
		drawCanvas();
	})();


	function drawCanvas() {
        /*
         * We can animate the line and the dots will still move, but they don't show up as well 
         * on a moving line. Look closely at the dots as the line slows down near the sides. They 
         * tend to shake a bit if the speed isn't just right. A stable line is much smoother.
         */
        
        var newX = (Math.sin(sineIncrement) * 250);
        startPoint.x = theCanvas.width/2 + newX - 40; // Slanting the line a bit.
        endPoint.x = theCanvas.width/2 + newX + 40;
        sineIncrement += .000;
        
        // Calculating these on each cycle so we can animate a moving line.
		var dy = endPoint.y - startPoint.y,
		    dx = endPoint.x - startPoint.x,
            lineAngle = Math.atan2(dy, dx),
            distance = getDistance(startPoint.x, startPoint.y, endPoint.x, endPoint.y),
            numDots = Math.floor(distance/spaceBetween),
            partialDistance = distance / numDots;

        
		context.fillStyle = 'rgba(255, 255, 255, 1)';
		context.strokeStyle = 'rgba(255, 255, 255, 1)';

		// Black background
		context.save();
			context.fillStyle = 'rgba(0, 0, 0, 1)';
			context.fillRect(0,0,theCanvas.width,...