7

I'm trying to resize an image map on window resize event. The closest I've gotten is to use a mouseclick event, but it needs to be window resize for what I'm doing. I'm using Firefox 3.5.5

I'm using jquery somewhat. Here's my example - the area button I want to resize on window resize is in the top left (click on it to resize map and area button):

http://www.whitebrickstudios.com/foghornstour/imagemap3.html

Any help would be appreciated! Thank you, Rich

Kozy
  • 2,691
  • 3
  • 18
  • 11

8 Answers8

5

I wrote some simple function to rebuild all map points on every event. Try this

function mapRebuild(scaleValue) {
    var map = $("#imgmap"); // select your map or for all map you can choose $("map").each(function() { map = $(this);.....})
    map.find("area").each(function() { // select all areas
        var coords = $(this).attr("coords"); // extract coords
            coords = coords.split(","); // split to array
        var scaledCoords = "";
        for (var coord in coords) { // rebuild all coords with scaleValue
              scaledCoords += Math.floor(coords[coord] * scaleValue) + ",";
            }
        scaledCoords = scaledCoords.slice(0, -1); // last coma delete
        $(this).attr("coords", scaledCoords); // set new coords
        });
    }

scaleValue can be calculated as oldWindowWidth/newWindowWidth. Of course you need to keep the value of oldWindowWidth on window resize. Maybe my solution not on time, but i hope this is useful to someone

Daniel Rikowski
  • 71,375
  • 57
  • 251
  • 329
  • 1
    +1 I'm using this function, works like a charm. But I used `img.width / img.naturalWidth` instead of using the window width. That way I didn't need to take any additional borders, margins, paddings, etc. into account. – Daniel Rikowski Sep 23 '13 at 09:55
  • 1
    I've expanded this out into a little lib, that keeps the map working as the image is resized and also copes with X and Y having different scaling. It also works out the scaling values for you. https://github.com/davidjbradshaw/imagemap-resizer – David Bradshaw Mar 12 '14 at 15:56
1

This is an old thread but for anyone looking for a solution for a similar or even identical problem, the ImageMapster jQuery plugin appears to provide the easiest solution. You can use its resize method (which can even animate the resizing if desired!) as follows to resize an image along with its image map:

$('img').mapster( 'resize', newWidth, newHeight, resizeTime);

You can find a link on ImageMapster's demo page to a jsFiddle that demonstrates resizing an image & its map in response to changing the browser window.

Mesagoma
  • 87
  • 7
1

I think what you want is at http://home.comcast.net/~urbanjost/semaphore.html

where I show different examples of how to make your image map coordinates change when your image display size changes.

urbanjost
  • 11
  • 1
  • I actually incorporated some of the code in those examples. The problem I ran into though, was that though the image map would resize for events like 'click', it would not adjust on 'window resize' event.--Well it does, you just have to resize the browser 6 times to get it to work. I'm using FF 3.5 Sorry my link went broke, it's fixed now: http://www.whitebrickstudios.com/foghornstour/imagemap3.html I've opted to use divs positioned by %s but it'd be really cool to get this working one day. – Kozy Dec 24 '09 at 19:58
0

As a modified version of Viktor's answer, this version can handle multiple resizes. It stores initial values for comparison against any future resize. This also uses waitForFinalEvent so it doesn't run over and over on resize.



    var mapImg = $('#mapImg');
    var naturalWidth = 1200; // set manually to avoid ie8 issues
    var baseAreas = new Array();
    var scaleValue = mapImg.width() / naturalWidth;

    $(window).resize( function() {
        waitForFinalEvent( function() {
            scaleValue = mapImg.width() / naturalWidth;
            mapRebuild( scaleValue );
        }, 500, 'resize-window');
    });

    function mapRebuild( scaleValue ) {
        var map = $("#imgMap");
        var mapareas = map.find( 'area' );
        if ( baseAreas.length == 0 ) {
            mapareas.each( function() {
                baseAreas.push( $(this).attr( 'coords' ) ); // set initial values
            });
        }
        mapareas.each( function( index ) {
            var coords = baseAreas[index]; // use the corresponding base coordinates        
            coords = coords.split( ',' );       
            var scaledCoords = '';
            for ( var coord in coords ) {
                scaledCoords += Math.floor( coords[coord] * scaleValue ) + ',';
            }
            scaledCoords = scaledCoords.slice( 0, -1 );
            $(this).attr( 'coords', scaledCoords );
        });
    }

    mapRebuild( scaleValue ); // initial scale

Community
  • 1
  • 1
Sean Michaud
  • 101
  • 1
  • 3
0

Here is a solution that does not use jQuery.

First, build a library function:

var ImageMap = {
    resize: function(coords, mapWidth) {
        var areas = document.getElementsByTagName('area'),
            imageWidth = document.querySelector("#map").clientWidth,
            resize = imageWidth / mapWidth;

        for (var i=0; i<coords.length; i++) {
            var temp = coords[i].map(x=>Math.round(x*resize));
            areas[i].coords = temp.join(',');
        }
    },
    getCoords: function(){
        var areas = document.getElementsByTagName('area'),
            array = [];
        for (var i=0; i<areas.length; i++) {
            array.push(areas[i].coords.split(',').map(x=>+x));
        }
        return array;
    }
};

Then, call the resize function when the page is initially loaded, and when it is resized:

var coords = ImageMap.getCoords();
window.onload = function () {
    ImageMap.resize(coords, 500);
}
window.onresize = function () {
    ImageMap.resize(coords, 500);
}

Replace 500 with whatever your default map size is

Kyle McCaf
  • 47
  • 5
0

a concret sample to recalculate coords of image map when window is loaded or resized:

this image is 1930 * 3360 :

  <div>
    <img id = "alhambra" src="filename.png" usemap="#image-map" width=100%>

    <map name="image-map">
        <area target="" alt="home" id = "home" title="home" href="" coords="1905,307,35,12" shape="rect">
        <area target="" alt="vaciado" id = "vaciado" title="vaciado" href="" coords="141,367,1783,631" shape="rect">
        <area target="" alt="tienda" id = "tienda" title="tienda" href="" coords="282,1408,278" shape="circle">
        <area target="" alt="stocks" id = "stocks" title="stocks" href="" coords="1300,2968,722,2699" shape="rect">
        <area target="" alt="whatsapp" id = "whatsapp" title="whatsapp" href="" coords="506,2980,1788,3193" shape="rect">
        <area target="" alt="direccion" id = "direccion" title="direccion" href="" coords="43,3215,1883,3324" shape="rect">
    </map>
  </div>

and add the script after body as:

</body>
<script>
  let text_home_coord = document.getElementById('home').coords;
  let text_vaciado_coord = document.getElementById('vaciado').coords;
  let text_tienda_coord = document.getElementById('tienda').coords;
  let text_stocks_coord = document.getElementById('stocks').coords;
  let text_whatsapp_coord = document.getElementById('whatsapp').coords;
  let text_direccion_coord = document.getElementById('direccion').coords;
  
  function img_map_response(){

    // get width and height in pixel
  var width_100_in_px = document.getElementById('alhambra').offsetWidth;
  var height_100_in_px = document.getElementById('alhambra').offsetHeight;

  // recalculate coords of image map
  function get_coor_resp(nombre_coords){

    // real width and height of image map
    var img_real_width="1930";
    var img_real_height="3360";

    // convert string coords to array
    text_array = nombre_coords.split(',');

    // rect
    if (text_array.length == 4) {
      // convert strig to integer
      x1 = parseInt(parseInt(text_array[0])*parseInt(width_100_in_px)/parseInt(img_real_width));
      y1 = parseInt(parseInt(text_array[1])*parseInt(height_100_in_px)/parseInt(img_real_height));
      x2 = parseInt(parseInt(text_array[2])*parseInt(width_100_in_px)/parseInt(img_real_width));
      y2 = parseInt(parseInt(text_array[3])*parseInt(height_100_in_px)/parseInt(img_real_height));
      // result converted in array of strings
      array_txt =[x1.toString(), y1.toString(), x2.toString(), y2.toString()]
      console.log("array_txt",array_txt)
      return array_txt.join(',')

    // circle
    } else {
      // convert strig to integer
      x1 = parseInt(parseInt(text_array[0])*parseInt(width_100_in_px)/parseInt(img_real_width));
      y1 = parseInt(parseInt(text_array[1])*parseInt(height_100_in_px)/parseInt(img_real_height));
      r = parseInt(parseInt(text_array[2])*parseInt(width_100_in_px)/parseInt(img_real_width));
      // result converted in array of strings
      array_txt =[x1.toString(), y1.toString(), r.toString()]
      return array_txt.join(',')        
    }
  }
  
 // set coords by recalculate coords (converted in string)
  document.getElementById('home').coords=get_coor_resp(text_home_coord);
  document.getElementById('vaciado').coords=get_coor_resp(text_vaciado_coord);
  document.getElementById('tienda').coords=get_coor_resp(text_tienda_coord);
  document.getElementById('stocks').coords=get_coor_resp(text_stocks_coord);
  document.getElementById('whatsapp').coords=get_coor_resp(text_whatsapp_coord);
  document.getElementById('direccion').coords=get_coor_resp(text_direccion_coord);
}
// add events load and resize for recalculate coords
window.addEventListener('load', img_map_response);
window.addEventListener('resize', img_map_response);
</script>

</html>
Fethi Pounct
  • 1,059
  • 5
  • 6
-1

To call a function when the window is resized, try the following:

$(window).bind('resize', function() {
    // resize the button here
});

Also, line 37 is missing a dollar sign:

scaleXY('theMap',(window).width());

It should be:

scaleXY('theMap',$(window).width());
Jordan Ryan Moore
  • 6,877
  • 2
  • 26
  • 27
  • 2
    Although you speak truth, the OP is already doing this if you bothered to read the code. – Crescent Fresh Nov 30 '09 at 19:34
  • So it works, but, I have to resize firefox 6 times in order for it to work. IE is a mess. I made those changes. This is helpful, but, it's looking like Firefox and especially IE are having too much trouble resizing. I'm thinking now that I'm going to stick with my original plan and just use semi-accurately positioned divs to take the place of image map buttons. Damn. I'll be thinking about this though and if I ever come up with and answer I'll post it. Thanks for your help guys. – Kozy Nov 30 '09 at 23:58
  • I had already "bothered" to read the code; however, the question itself didn't make it clear that this part of the solution wasn't the problem. I added the basic resize event handling for those who might find this later when searching for a solution. The second half of my question did address one of the problems with the code, so I'm unsure why I should receive a downvote. – Jordan Ryan Moore Jan 08 '10 at 17:21
-1

If you only need to resize the image, use this technique: http://www.cssplay.co.uk/layouts/background.html

Thanks to CSSPlay.

danigb
  • 711
  • 6
  • 13
  • 2
    I think you're missing the point danigb. I'm looking to resize an 'image map area', on window resize. – Kozy Dec 02 '09 at 17:47
  • Now I understand. In fact, i've opened your url and it didnt work for me (chrome). I had to do something similar and I ended using divs instead of imagemaps and setting the position: absolute; and top, left, width and height in % units. If you what i can explain a little bit more. cheers dani – danigb Dec 09 '09 at 16:49
  • Hey Danigb, I ended up using divs as well to position images with %s. Though it'd still be cool to use image maps in a future version. This is what I have for image maps so far. http://home.comcast.net/~urbanjost/IMG/resizeimg4.html – Kozy Dec 24 '09 at 19:17
  • woops, meant to use this link: http://www.whitebrickstudios.com/foghornstour/imagemap3.html – Kozy Dec 24 '09 at 19:17