I'd been toying with the idea of learning Flash, and before I gave up based soley on it's unbelievably cumbersome interface I came across actionscripts.org, a great site which has a great list of tutorials for people who are not so easily put off by development environments that require a screen resolution of 10 miles by 8 miles.

I found this slick piece of Flash by Joshua Davis and thought to myself..."ok...if you can write that in javascript, then you won't have to learn Flash."

So, there it is. Granted I had to make some exlusions for non-IE browsers because they couldnt seem to do things quickly enough during the mouseover event to keep from bogging down, but I think it's pretty close. Interestingly enough, it works better in Opera 7.10 than it does in Netscape 7 or Mozilla 1.3 on Windows 98/2K/XP. It does not work so well on Mozilla 1.4 or Netscape 7 on my Linux box.

I'll probably still learn Flash though.

The Source:

ua = navigator.userAgent.toLowerCase();
ns = ua.indexOf("netscape");

var MIN_SIZE=6;
var MAX_SIZE=16;
var MAX_PADDING=10;
var MIN_PADDING=0;

var currentFontSize = new Array()
var currentPadding = new Array();
var hasMouse = new Array();
var mInterval;
var currentColor = new Array();
var currentPaddingTop = new Array();

var linkText = new Array("01. one","02. two","03. three","04. four","05. five","06. six","07. seven","08. eight","09. nine","10. ten","11. eleven","12. twelve","13. thirteen","14. fourteen","15. fifteen","16. sixteen","17. seventeen","18. eighteen");

function init() {
	mHTML = "";
	for(i=0;i<linkText.length;i++) {
		mHTML+='<div class="waveDiv" name="tsunami" id="tsunami" onmouseout="startNormalizeInterval()" onmousemove="setMouse(' + i + ');">' + linkText[i] + '</div>';
		currentFontSize[i]=6;
		currentPadding[i]=0;
		hasMouse[i] = 0;
		currentColor[i] = "#646464";
		currentPaddingTop[i] = 5;
	}
	document.getElementById("mContainer").innerHTML = mHTML;
}

function setMouse(objID) {
	clearInterval(mInterval);
	hasMouse[objID]=1;
	resetHasMouse(objID);
	changeFont();
}

function startNormalizeInterval() {
	mInterval = setTimeout("startNormalize()",200);
}

function startNormalize() {
	clearInterval(mInterval);
	mInterval = setInterval("normalize()",100);
}

function normalize() {
	for(i=0;i<currentFontSize.length;i++) {
		if(currentFontSize[i] > MIN_SIZE)currentFontSize[i]--;
		if(currentPadding[i] > MIN_PADDING)currentPadding[i]--;
		if(currentFontSize[i] == MIN_SIZE) { 
			currentPaddingTop[i]=5;
			document.getElementsByName("tsunami")[i].style.color = "#646464";
		}

		document.getElementsByName("tsunami")[i].style.fontSize = currentFontSize[i];
		document.getElementsByName("tsunami")[i].style.paddingLeft = currentPadding[i];
		document.getElementsByName("tsunami")[i].style.paddingTop = currentPaddingTop[i];
		
	}
	
	if(isNormal())clearInterval(mInterval);
}

function isNormal() {
	for(i=0;i<currentFontSize.length;i++)if(currentFontSize[i] != MIN_SIZE)return false;
	return true;
}

function resetHasMouse(newObj) {
	for(i=0;i<hasMouse.length;i++) {
		if(hasMouse[i] && i!=newObj) {
			hasMouse[i]=0;
			break;
			return;
		}
	}
}

function changeFont() {
	for(i=0;i<currentFontSize.length;i++) {
		if(hasMouse[i]) {
			if(currentFontSize[i] < MAX_SIZE) {
				currentFontSize[i]++;
				if(currentPadding[i]<MAX_PADDING)currentPadding[i]++;
				currentPaddingTop[i]=0;
				currentColor[i] = "#C8C8C8";
			} else if(currentFontSize[i] == MAX_SIZE) {
				currentColor[i] = "#CDCDCD";
			}
		}  else {
			zNeighbor = neighborHasMouse(i);
			if(zNeighbor) {
				if(currentFontSize[i] < returnNeighborMaxSize(zNeighbor)) {
					currentFontSize[i]++;
					if(currentPadding[i]<returnNeighborMaxPadding(zNeighbor))currentPadding[i]+=2;
					currentPaddingTop[i]=0;
					currentColor[i] = "#C8C8C8";
				} else {
					currentFontSize[i] = returnNeighborMaxSize(zNeighbor);
					currentPadding[i] = returnNeighborMaxPadding(zNeighbor);
				}
			} else {
				if(currentFontSize[i]>MIN_SIZE) {
					if(currentFontSize[i]>MIN_SIZE)currentFontSize[i]--;
					if(currentPadding[i]>MIN_PADDING)currentPadding[i]--;
					if(currentPaddingTop[i]<5)currentPaddingTop[i]++;
					currentColor[i] = "#646464";
					currentPaddingTop[i]=5;
				}
			}
		}
	if(!hasMouse[i] && currentColor[i]!="#969696")currentColor[i] = "#969696";
	
	document.getElementsByName("tsunami")[i].style.fontSize = currentFontSize[i] + "px";
	// if this is Netscape, dont bump the left padding up.
	if(ns==-1)document.getElementsByName("tsunami")[i].style.paddingLeft = currentPadding[i];
	//if this is IE and nothing else, bump the top padding
	if(document.all)document.getElementsByName("tsunami")[i].style.paddingTop = currentPaddingTop[i];
	// if this is IE or Mozilla, change the font colors
	if(document.all || ns==-1)document.getElementsByName("tsunami")[i].style.color =currentColor[i];
	}
}

function returnHasMouse() {
	for(i=0;i<hasMouse.length;i++)if(hasMouse[i])return i;
}

function returnNeighborMaxPadding(neighborDistance) {
	if(neighborDistance == 1 || neighborDistance == -1)return MAX_PADDING-6;
	if(neighborDistance == 2 || neighborDistance == -2)return MAX_PADDING-10;
}
function returnNeighborMaxSize(neighborDistance) {
	if(neighborDistance == 1 || neighborDistance == -1)return MAX_SIZE-3;
	if(neighborDistance == 2 || neighborDistance == -2)return MAX_SIZE-4;
}

function neighborHasMouse(objID) {
	distance = new Array(1,-1,-2,2);
	for(e=0;e<distance.length;e++) {
		if(hasMouse[objID+distance[e]]) {
			return distance[e];
			break;
		}
	}
	return 0;
} 


Tsunami Text Effect v1.0
last revision: 08.11.2003
steve@slayeroffice.com
http://www.slayeroffice.com