Dynamically resizing Image-maps and images

I wrote a small little lib to keep an imageMap scaled to a resizable image, so the map stays in sync as the image scales. Useful when you want to map a percentage scaled image etc.

It can be used with or without jQuery.

https://github.com/davidjbradshaw/imagemap-resizer

and you can see it working at.

http://davidjbradshaw.com/imagemap-resizer/example/


If you end up to do the task with JavaScript, here is a cross-browser codesnippet to resize all areas in MAP element.

window.onload = function () {
    var ImageMap = function (map) {
            var n,
                areas = map.getElementsByTagName('area'),
                len = areas.length,
                coords = [],
                previousWidth = 1920;
            for (n = 0; n < len; n++) {
                coords[n] = areas[n].coords.split(',');
            }
            this.resize = function () {
                var n, m, clen,
                    x = document.body.clientWidth / previousWidth;
                for (n = 0; n < len; n++) {
                    clen = coords[n].length;
                    for (m = 0; m < clen; m++) {
                        coords[n][m] *= x;
                    }
                    areas[n].coords = coords[n].join(',');
                }
                previousWidth = document.body.clientWidth;
                return true;
            };
            window.onresize = this.resize;
        },
        imageMap = new ImageMap(document.getElementById('map_ID'));
    imageMap.resize();
}

previousWidth must be equal to the width of the original image. You also need to use some relative units in HTML:

<div style="width:100%;">
<img id="Image-Maps_5201211070133251" src="Site.png" usemap="#Image-Maps_5201211070133251" border="0" width="100%" alt="" />

Working demo at jsFiddle. If you open the fiddle in IE, you can actually see AREAs when clicking them.


As a class (ES6):

class ResponsiveImageMap {
    constructor(map, img, width) {
        this.img = img;
        this.originalWidth = width;
        this.areas = [];

        for (const area of map.getElementsByTagName('area')) {
            this.areas.push({
                element: area,
                originalCoords: area.coords.split(',')
            });
        }

        window.addEventListener('resize', e => this.resize(e));
        this.resize();
    }

    resize() {
        const ratio = this.img.offsetWidth / this.originalWidth;

        for (const area of this.areas) {
            const newCoords = [];
            for (const originalCoord of area.originalCoords) {
                newCoords.push(Math.round(originalCoord * ratio));
            }
            area.element.coords = newCoords.join(',');
        }

        return true;
    };
}

Usage:

var map = document.getElementById('myMapId');
var image = document.getElementById('myImageId');
new ResponsiveImageMap(map, image, 800);

You can multiply the coordinates by the ratio of the original image and the styled image.

<img id="paredea" usemap="#PAREDE-A"  src="https://i.imgur.com/o9nrUMR.png">

    <map name="PAREDE-A">
        <area id="paredea0" shape="rect"  onclick="alert('colmeia A')">
        <area id="paredea1" shape="rect"  onclick="alert('colmeia B')">
        <area id="paredea2" shape="rect"  onclick="alert('colmeia C')">
        <area id="paredea3" shape="rect"  onclick="alert('colmeia D')">
        <area id="paredea4" shape="rect"  onclick="alert('colmeia E')"> 

        <area id="paredea5" shape="rect"  onclick="alert('comeia F')">
        <area id="paredea6" shape="rect"  onclick="alert('colmeia G')">
        <area id="paredea7" shape="rect"  onclick="alert('colmeia H')">
        <area id="paredea8" shape="rect"  onclick="alert('colmeia I')">
        <area id="paredea9" shape="rect"  onclick="alert('colmeia J')">  

        <area id="paredea10" shape="rect"  onclick="alert('colmeia K')">
        <area id="paredea11" shape="rect"  onclick="alert('colmeia L')">
        <area id="paredea12" shape="rect"  onclick="alert('colmeia M')">
        <area id="paredea13" shape="rect"  onclick="alert('colmeia N')">
        <area id="paredea14" shape="rect"  onclick="alert('colmeia O')">  
    </map>

    <script>


        var coordsA = [];
        coordsA[0] = "0,0,200,130";
        coordsA[1] = "200,0,400,130";
        coordsA[2] = "400,0,600,130";
        coordsA[3] = "600,0,800,130";
        coordsA[4] = "800,0,1000,130";

        coordsA[5] = "0,160,200,240";
        coordsA[6] = "200,160,400,240";
        coordsA[7] = "400,160,600,240";
        coordsA[8] = "600,160,800,240";
        coordsA[9] = "800,160,1000,240";

        coordsA[10] = "0,270,200,400";
        coordsA[11] = "200,270,400,400";
        coordsA[12] = "400,270,600,400";
        coordsA[13] = "600,270,800,400";
        coordsA[14] = "800,270,1000,400";


        function setcoords(areaid, totalOfAreas) {
            document.getElementById('paredea').style.width = "auto";
            var width1 = document.getElementById('paredea').width;
            document.getElementById('paredea').style.width = "100%";
            var width2 = document.getElementById('paredea').width;
            var ratio = width2 / width1;

            for (var i = 0; i < totalOfAreas; i++) {
                var temp = coordsA[i].split(",");
                var newcoords = "";
                for (var j = 0; j < temp.length; j++) {
                    temp[j] *= ratio;
                    newcoords += temp[j] + ",";
                }
                newcoords = newcoords.substr(0, newcoords.length - 1);

                document.getElementById(areaid + i).coords = newcoords;
            }
        }


       window.onload = function () {
            setcoords("paredea", 15);
        };

        window.onresize = function () {
            setcoords("paredea", 15);
        };
    </script>