An Interactive US Map Without Flash

A client recently requested a feature for their website that would allow users to access state by state data by rolling over a map of the US. At first, I considered using one of the available Flash packages, but the design took a couple of twists that made that much more difficult. So I opted to implement the map with plain old HTML, CSS and Javascript.

Here is the map.

The benefit of using HTML, CSS and Javascript instead of Flash, is that the map will function in just about any browser without having to install additional components. Mobile browsers such as Safari on iPhone, older browsers, or browsers without Javascript enabled, can still use the map. Here is how it works.

The map consists of three layers.

layers

The bottom layer contains the full map as a background image. This loads when the page is opened, along with the top layer which contains the maparea linked to a transparent GIF that matches the size of the map. The layers are positioned over one another with CSS.

div#usmap{
position: absolute;
top: 0px;
left: 0px;
}

div#mapareas{
position: absolute;
top: 0px;
left: 0px;
z-index: 99;
}

The middle layer is where all of the animation takes place. When a user mouses over one of the mapareas, jQuery prepends the preloaded image for an individual state and positions it in the middle layer. Some images also have a corresponding mask to maintain the illusion that the state is popping up away from the page. The individual state images were created by cutting apart the main US image, and the positioning is done with jQuery’s css method. This can be somewhat time consuming for complex maps.

$("#usmap").prepend(img);
$("#usmap").prepend(imgmask);
positionimage();
.state-copy {
position: absolute;
z-index:2;
}
.state-mask {
position: absolute;
z-index:1;
}

Then jQuery calcuates the current size and zoomed size, and executes the animation.

$(".state-copy").each(function(){
var width = $(this).width();
var height = $(this).height();

var zoomheight = height * 1.2;
var zoomwidth = width * 1.2;

var	centerheight = (zoomheight - height)/2;
var	centerwidth = (zoomwidth - width)/2;

$(this).animate({
top: '-=' + centerheight,
left: '-=' + centerwidth,
width: zoomwidth,
height: zoomheight
}, 100);

});

This method will work for just about any similar image that you want to animate.

Please Take a Number

In the Internet world of seemingly endless computer resources, it’s not often that a website requires visitors to wait in line to visit, but a recent Dancing Mammoth project called for just that.

The Requirements:

  • Visitors will be added to a Virtual Waiting Room prior to advancing to website content.
  • Visitors will be advanced according to First In First Out.
  • Page must indicate current position in line via a client provided Flash object.
  • An administrator must be able to control flow of traffic.

The client expected light traffic to their video chat feature, so we decided that capturing queue data in a single table was the most efficient way to go. We could then poll at a some set interval to determine a visitor’s place in line, and take action based on the result.

The client-provided Flash object required use of a bit of javascript, so I decided to go ahead and implement the polling with the jQuery library’s ajax functionality — I ♥ jQuery. Here’s what the javascript function looks like:

function updatePosition()
{
	$.ajax({ 
		type: "GET", 
		url: "queue/index.php", 
		data: "sess=<?php echo $session_id ?>&random=" + new Date().getTime(), 
		dataType: "xml", 
		success: function(xml){
			var ky = "";
			var val = "";
			var action = "";
			var pos = 0;
			$("response", xml).each(function(){
				$("action", this).each(function(){
					action = $("key", this).text();
					val = $("value", this).text();
					if(action == "forward")
					{
						// Forward
						forwardToUrl(val);
					}else{
						//Update
						pos = val;
						thisMovie('queueCountdown').update(pos); 
					}	
				});
			});
		}	
	});
}

If you’d like to review all the sample files, you can download them here, but no warranty is expressed or implied.

jQuery sends the visitor’s session id (as well as a random string — always send a random string when making ajax GET calls or IE will give you cached content) to a script that checks the queue and returns some XML with the action and associate value. Then the visitor is either forward to the content, or their position in line is displayed.

On the back end, the VirtualWaitingRoom class provides functionality to retrieve queue position, administratively advance visitors through the queue, and remove records for abandoned sessions.

The project was a success and while there’s nothing especially complex about it, this Virtual Waiting Room is a good short example of how various web technologies can come together to provide a unique solution.