maphilight: image map mouseover highlighting

I just released maphilight, a jQuery plugin that turns image maps into wonderful graphical masterpieces.

Image maps aren’t so popular any more, for some strange reason. So a quick definition: an imagemap is an <img> with the usemap attribute, pointing to a <map> that describes polygons that link places within that image.

This sprung from me wanting to display pretty highlighting of countries on a map, but not wanting to mess with flash for it. It involves enough annoying fiddling with <canvas> (and VML, because IE is in the stone age) that I feel I’m saving other people a decent amount of work by releasing it.

Simple demo
Pretty demo using a world map
Documentation
Download (requires jQuery)

(Tools like “ HTML-Image map Creator WYSIWYG” might be handy if you want to make image maps yourself.)

Comments (25)

  1. Discover your plugin and I liked a lot, on this website I could make a small development with drupal and Maphiligh.

    If you want to see it working this is the link:
    http://www.economiasolidaria.org/mapas/
    Thank you for your work.

    Greetings

    http://www.investic.net/blog/karlos/

    Monday, May 19, 2008 at 7:41 am #
  2. marc wrote::

    hi david,
    great plugin. and smart done. i wondered some time how you get borders around non rectangles. then i peeked into the plugin and saw you did it with canvas. very nice!
    but maybe you can help me with a question?
    i need an option to have one area active by default. like your alwaysOn option, but not for the whole map, but one area. would this be possible??

    i’m like 90% done and now i can’t find a way to do this :-(

    best regards,
    marc

    Wednesday, July 23, 2008 at 7:48 am #
  3. David wrote::

    Hi Marc,

    You can see that sort-of working if you look at the in-development code.

    It’s updated so that, if you’re using jQuery’s Metadata plugin then you can give individual areas the alwaysOn option. Take a look at demo_simple.html for an example.

    It works perfectly in Firefox and Safari, but the alwaysOn shapes don’t appear at all in IE currently. It’s a layering thing, I think — the alwaysOn ones are being rendered behind everything else.

    It’s sort of awkward for me to debug on IE at the moment, so this is likely to advance in fits and starts. If you decided to take a look at it yourself and made any progress, I’d be happy to accept patches.

    Thursday, July 24, 2008 at 10:01 pm #
  4. Dena wrote::

    Hi David,

    Love what you’ve put together here–well done.

    I was wondering if you planned to add any functionality that would highlight all shapes that share a title (i.e.: all of Hawaii instead of just one island at a time). I can see how it could be done, but don’t have the programming chops to do it.

    Thanks!

    Sunday, July 27, 2008 at 6:20 pm #
  5. Billy wrote::

    I love the alwaysOn feature. I hope you can debug it for IE since 90% of the browsers in use are IE.

    Wednesday, August 13, 2008 at 6:01 am #
  6. Billy wrote::

    David,

    I’ve been debugging the maphilight.js code and it looks like $.fn.maphilight is not being called in IE. I put an alert statement as the first line of the $.fn.maphilight function and it gets called in firefox, but not in IE.. Could this be the problem?

    Great app!

    Friday, August 15, 2008 at 5:10 am #
  7. Billy wrote::

    sorry, the function does get called but for some reason the alert is handled right.. I hope that this somehow gives you an idea of where the error could be coming from..

    Thanks!

    Friday, August 15, 2008 at 5:25 am #
  8. Tim wrote::

    Hi David,

    First of all, thanks for this great piece of code.

    I’m using your feature to implement a postalcode map of The Netherlands. The highlighting works smoothly. I also added overlib with a mouseover event to communicate the postalcode region including two or tree major cities inside the postal region. I’m trying to make the map work together with Xajax. Based on an onclick event i’m calling a Xajax function to save the clicked postalcode region in the database. What i would like to do after the xajax call is highlight the clicked region as AlwaysOn (using class=”{stroke:false, fillColor:’EAEAEA’, fillOpacity:0.2, alwaysOn:true}” on the area element).

    I assign this class element using something like $objResponse->assign(’area_id’, ‘class’, “{stroke:false, fillColor:’EAEAEA’, fillOpacity:0.2, alwaysOn:true}”);

    The thing is it will not highlight with always on.

    I tried to call $objResponse->script(”$(’.map’).maphilight({fade: false})”); after the class assignment but it will not show. Is there a(nother) way to dynamically show the always on highlight?

    Thanks Tim.

    Thursday, August 21, 2008 at 4:44 am #
  9. David wrote::

    Tim,

    This wasn’t possible until about 5 minutes ago. I just changed how it works — it used to refuse to touch an image a second time, now it cleans up all the cruft it put around it and regenerates with the new options.

    All you have to do is call `$(’#your_image_id’).maphilight(options)` again, and it’ll regenerate everything, including any changes you’ve made to the individual area tags.

    Take a look at http://github.com/kemayo/maphilight/tree/master to see this in action — it’s currently not in an officially released version.

    Let me know if this works for you — if it does, it’s time for another release, and if it doesn’t, I’ll play with it a bit more to get things working right.

    Friday, August 22, 2008 at 9:07 pm #
  10. Tim wrote::

    Hi David, Thanks for your fast reply. This really helps me getting a step further. Now i kan dynamically reload the map by using the new call method. For example: $(’#image_id’).maphilight({fade : false}).

    Using this method it’s possible to call this from Xajax an reinit the map. Thats great. Now comes the ‘but’. The problem seem to occur with the metadata and always on feature. After selecting an area and execute a xajax command on the onclick event + reloading the map with the new feature it does not see the always on setting on line 165 (new version on github) if you put an alert between the lines 165 and 166: if(area_options.alwaysOn) { alert(’alwayson’);
    if(!canvas_always) {

    it doesn’t see a class=”{metadata-options}” just set with xajax.

    it only sees hardcoded metadatasettings. On page load i also assign the metadata class so at that point everything is fine. It seems a context problem. I’ll try to figure out if this could be fixed.

    I also experience a ‘glitch’ if you put the image map inside a div which had a style display:none;. The metadata / always on area’s will not display. I played a little with visibility instead of display:none/block. If you use visibility instead of display the areas will be filled but visibility had it’s limitations.

    Saturday, August 23, 2008 at 2:33 am #
  11. Tim wrote::

    Some progress…

    It seems Xajax cannot assign a class attribute to a area-element. Metadata can be pulled out of a class=”{options}”, data=”{options}” of a tag inside te element. The last option will not work because we cannot close an area tag. So script cannot be surrounded by this tag. This leaves us with class and data. Also data cannot be used. I think due top the fact it’s not DOM on the area element. I tried to use the ‘lang’ attribute for testing. This you can assign to the area element using Xajax and if you use this init:

    $(function() {
    $.metadata.setType(”attr”, “lang”);
    $(’.map’).maphilight({fade: false});
    });

    It will be picked up if you reload the page. So i can conclude metadata could be read out of the ‘lang’ attribute. (remember this is testing and maybe a workaround not a real solution).

    I tell xajax to first assign the metadata to the lang attribute and after complete a second xajax call to reload the map with the new feature. But to bad still, although the metadata is now for sure present in the area element (inside the lang-attr.) is will nog mark it as AlwaysOn on the reloaded map….

    Saturday, August 23, 2008 at 4:22 am #
  12. Tim wrote::

    Made a stupid mistake… you can infact assign a class to AREA with assign className. But it still not shows it as always on on mapreload.

    Sunday, August 24, 2008 at 2:56 am #
  13. Daniel wrote::

    Hi,
    I have a small problem. My map contains area into area and I am needing fill only outer area. Heve you any ideas?

    Saturday, August 30, 2008 at 5:25 am #
  14. Nielsos wrote::

    David, thanks for this great script; it works smoothly!

    I made a few modifications so the user is able to select and de-select a shape. I believe this mod solves Tim’s problem as well.

    The script, and a working example can be found on the following location: http://formidablo.nl/jquery/.

    Grtz,

    Nielsos

    Friday, September 5, 2008 at 3:23 am #
  15. Nielsos wrote::

    I forgot to mention that every shape should have an id-tag with a unique value.

    Friday, September 5, 2008 at 3:26 am #
  16. Nielsos wrote::

    I’ve added extra functionality:

    Link shapes with the “linked” attribute. Every shape with the same linked value will be turned on and off simultaneous

    Example: class=”{alwaysOn:true,linked:1}”

    http://formidablo.nl/jquery/index.html

    Sunday, September 7, 2008 at 6:21 am #
  17. Felix Nagel wrote::

    Hey there, cool script but is there any option (or can you tell me where to start implementing it) to highlight an area from outside? For example by pressing a button?

    Tuesday, September 23, 2008 at 8:33 am #
  18. some map guy wrote::

    Great work on this plugin. Anyone else have problems with it working on IE7? Seems to have hilite at all on:

    http://davidlynch.org/js/maphilight/docs/demo_simple.html

    Works great in all other browsers I’ve tested. Could there be a small annoying IE idiosyncracy that prevents this from working?

    Wednesday, September 24, 2008 at 8:52 am #
  19. Ian Tresman wrote::

    Very nice plug-in. I’d very much like to add some text to the highlighted area. Is it possible to have an associated floating DIV (like a tooltip). I want to show captions based on the AREA’s title tag.

    Tuesday, October 7, 2008 at 10:32 am #
  20. Pinney wrote::

    Great plugin. I’m trying to figure out how to toggle the highlight when a map area is clicked. I will figure it out eventually, but figured I’d check w/you b/c I figure there’s probably just one line of code necessary to do it that I haven’t figured out yet.

    Thursday, October 9, 2008 at 10:51 am #
  21. Ian Tresman wrote::

    I’d love to add a caption based on the image map AREA title tag, but I can’t figure out how to show any text with canvas-generated maphilight.

    Monday, October 13, 2008 at 7:15 am #
  22. Ian Tresman wrote::

    If I try and print an image to which maphilight is associated, the image does not appear. Is there a way to disable Maphilight when I print, or some CSS that can be placed inside
    @media print { .. }

    Saturday, October 18, 2008 at 2:57 pm #
  23. Kit Eglinton wrote::

    Thanks for a brilliant plugin. As a newbie to jquery, is there an easy way to trigger other stuff from inside your code. I’m hiding/showing text depending on an area of the image? Thanks again

    Wednesday, November 19, 2008 at 6:44 am #
  24. john wrote::

    alwaysOn does not seem to be working with IE. In the simple demo the squid does not have solid colouring.

    Monday, November 24, 2008 at 4:38 pm #
  25. nielsos wrote::

    Pinney, see http://formidablo.nl/jquery/index.html

    for a example!

    Thursday, December 4, 2008 at 7:33 am #