MoveableMap is a javascript library that allows you to turn any block of HTML into a draggable, moveable entity within a viewport. Similar to the behavior of Google Maps, but hopefully very easy to implement. On the right here, you can see a real simple example; it’s just a div block with an img element in the middle of it.

How simple is the code for this example? The moveableMap library is built on top of the fantastic prototype.js library, the slick scriptaculous library, and the enlightening Low Pro library. It takes just a little CSS magic and a little unobtrusive javascript to get the behavior you see here.

We need two elements: the “container” block, and the block inside the viewport. In this example, they’ll both be divs.

Our CSS sets us up:

1
2
3
4
5
6
7
8
9
10
11
12
#map_holder {    /* the 'container' */
  width: 256px; height: 256px;            /* size of the viewable area */
  overflow: hidden; position:relative;    /* necessary to make the whole thing work */
  padding:0px; border: 3px dotted #990;   /* aesthetics */
}

#the_map {   /* the inner block */
  width: 512px; height: 512px;   /* defining the size keeps us from getting squashed */
  left:-128px; top:-128px;       /* the starting offset - always negative */
  position:relative;             /* better believe it, you need it */
  border:3px solid #550;         /* so we can see the edge of the map */
}

A little javascript to create the MoveableMap object and apply some behaviors:

1
2
3
4
5
6
7
8
9
10
11
12
// we don't attempt anything until the DOM is loaded
Event.observe(window, 'load', function() {
  // create a new MoveableMap object and pass in the two elements we need
  // I'm using the prototype shortcut $('my_html_id') to represent an element:
  mainMap = new MoveableMap($('the_map'), $('map_holder'));
  // here's the Low Pro unobtrusive helper:
  Event.addBehavior({
    // specify the CSS selector for the inner block and 
    // apply the MapDrag behavior to it (specifying the MoveableMap object)
    '#the_map' : MapDrag(mainMap)
  });
});

And the HTML, which is pretty trim:

1
2
3
4
5
<div id="map_holder">
  <div id="the_map" style="background: url(/examples/map/images/fakemap.jpg)">
     <!- just empty to give us a div with a image background -->
  </div>
</div>

Notice the lack of onclick, onmousedown, onmouseup in the HTML? That’s the unobtrusive bit, baby. All that stuff is handled by the MoveableMap library (as Behaviors a la Low Pro).

Let’s see some more impressive examples. Here’s something similar to what’s on the page here, but with a compass in the corner that you can click on to slide the map in that direction. Double-click to slide all the way to the edge. Take note of the fake HTML attribute called ‘mapdir’ inside each compass direction.
Check it: Old World Map with Compass

That was fun. What else you got? Here’s a (crudely drawn) map of Aethora. The ‘compass’ from the previous example has been placed around the edges of the map to give the viewer a feeling of clicking on the sides of the map to make it scroll. Additionally, you can see a list of cities below the map – click on any city to make the map slide to that location. In reality, the ‘cities’ are positioned div elements. The clickable element has a fake HTML attribute, targetelement, which names the id of the element you want to center the map on.
Peep: Fantasy map with clickable city names

This last map is more of the same really, but the big deal is that the inner block of code is a table. It’s basically here to prove to you that you can put some pretty complex stuff on the inside (not just a jpg of a street map) and still move the map around. This example is closer to the actual purpose I created this library for (Aethora, my RPG written in Ruby on Rails and javascript).
Observe: Tiled (table-based) ‘battle field’

Here’s the MoveableMap js file. You’ll need to load prototype, the scriptaculous effects.js library, Low Pro, MoveableMap, and then your own javascript in that order. Check out the source code of those examples above for more details. The code seems to work well in Firefox, IE6, and IE7. In Opera, it seems to do a slight, 3-4 pixel detour before getting on track when using the compass movement. If anyone can tell me how to fix it, I’ll buy you a beer/coffee (I had to sell my soul just to get it to work in IE). I haven’t had a chance to test it in Safari or anything else, but I’d love to hear how it works out.

So enjoy – and let me know if you find any bugs. And definitely let me know if you find it useful!

Update: Here’s a great example, this one provided Kahil, who is the developer of a browser-based game called WMD Tank Battle: Vertical Scrolling a la old school arcade shooters

Leave a Reply