18

I need to create something like this:

http://www.mrporter.com/journal/journal_issue71/2#2

where every product in my big image is associated with a tooltip which appears on mouse hover. But I need this to work with fullscreen images.

The first solution I thought (as the example above) is the map html solution where each fill up exactly the boundaries of my products. The problem is that I can't indicate precise values for my because my image size depends on window screen.

The best solution would be the possibility to set percentage values for my area. Is this possible? Any other suggestions ?

Rndm
  • 6,710
  • 7
  • 39
  • 58
Stefano Ortisi
  • 5,288
  • 3
  • 33
  • 41
  • images have defined dimensions, why use percentage? assuming you're not stretching the images to fill the screen (which is considered bad practice). – Eliran Malka Jul 06 '12 at 13:59
  • 8
    My images will definitely stretching to fit the entire window browser. And if you manage your images carefully (providing for example different version using media queries or other techniques), then it isn't a bad practice. – Stefano Ortisi Jul 06 '12 at 14:06
  • well, if you assign a different image for each screen size, you should be able to use fixed dimensions for the map's `area`s. see @Baszz's answer. – Eliran Malka Jul 06 '12 at 14:29
  • I think he's doing something more fluid, a la http://srobbin.com/jquery-plugins/backstretch/ – technoTarek Jul 06 '12 at 15:16
  • exaclty @technoTarek. But I think that i shall script some tricky JS solution, as Baszz said. – Stefano Ortisi Jul 06 '12 at 15:24
  • @Stefano, hopefully my answer might help you out some in achieving your JS solution. =/ – David Thomas Jul 06 '12 at 18:22

7 Answers7

27

Alternative solution using links:

CSS:

.image{
  position: relative;
}
.image a{
  display: block;      
  position: absolute;
}

HTML:

<div class="image">
  <img src="image.jpg" alt="image" />
  <a href="http://www.example.cz/1.html" style="top: 10%; left: 10%; width: 15%; height: 15%;"></a>
  <a href="http://www.example.cz/2.html" style="top: 20%; left: 50%; width: 15%; height: 15%;"></a>
  <a href="http://www.example.cz/3.html" style="top: 50%; left: 80%; width: 15%; height: 15%;"></a>
</div>

Percentage dimensions can be detected in graphic editors

Gary Reckard
  • 277
  • 2
  • 13
hrozino
  • 271
  • 3
  • 2
5

There is a jQuery plugin for this jQuery RWD Image Maps.

You might want to integrate my pending pull request (manually) to support "width=100%": https://github.com/stowball/jQuery-rwdImageMaps/pull/10

blueyed
  • 27,102
  • 4
  • 75
  • 71
4

you can check this this plugin is life saving.

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/

Siful Islam
  • 1,906
  • 3
  • 21
  • 31
3

Because this can't be done with simple HTML/CSS manipulation, the only alternative is JavaScript to, effectively, recalculate the coordinates based on the resizing of the image. To this end I've put together a function (though there's two functions involved) that achieves this end:

function findSizes(el, src) {
    if (!el || !src) {
        return false;
    }
    else {
        var wGCS = window.getComputedStyle,
            pI = parseInt,
            dimensions = {};
        dimensions.actualWidth = pI(wGCS(el, null).width.replace('px', ''), 10);
        var newImg = document.createElement('img');
        newImg.src = src;
        newImg.style.position = 'absolute';
        newImg.style.left = '-10000px';
        document.body.appendChild(newImg);
        dimensions.originalWidth = newImg.width;
        document.body.removeChild(newImg);
        return dimensions;
    }
}

function remap(imgElem) {
    if (!imgElem) {
        return false;
    }
    else {
        var mapName = imgElem
            .getAttribute('usemap')
            .substring(1),
            map = document.getElementsByName(mapName)[0],
            areas = map.getElementsByTagName('area'),
            imgSrc = imgElem.src,
            sizes = findSizes(imgElem, imgSrc),
            currentWidth = sizes.actualWidth,
            originalWidth = sizes.originalWidth,
            multiplier = currentWidth / originalWidth,
            newCoords;

        for (var i = 0, len = areas.length; i < len; i++) {
            newCoords = areas[i]
                .getAttribute('coords')
                .replace(/(\d+)/g,function(a){
                    return Math.round(a * multiplier);
                });
            areas[i].setAttribute('coords',newCoords);
        }
    }
}

var imgElement = document.getElementsByTagName('img')[0];

remap(imgElement);​

JS Fiddle demo.

Please note, though, that this requires a browser that implements window.getComputedStyle() (most current browsers, but only in IE from version 9, and above). Also, there are no sanity checks other than ensuring the required arguments are passed into the functions. These should, though, be a start if you want to experiment.

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
1

Percentages in image maps are not an option. You might want to get some scripting involved (JS) that recalculates the exact position on images resize. Of course, in that script you can work with percentages if you want.

Bas Slagter
  • 9,831
  • 7
  • 47
  • 78
0

Consider using the Raphaël JavaScript Library with some CSS. See http://raphaeljs.com/ and Drawing over an image using Raphael.js.

Community
  • 1
  • 1
technoTarek
  • 3,218
  • 2
  • 21
  • 25
0

I know this is an old question but maybe someone needs this at some point as I did. I modified @David Thomas' answer a bit to be have this little piece of JS be able to handle future recalculations:

function findSizes(el, src) {
    if (!el || !src) {
        return false;
    }
    else {
        var wGCS = window.getComputedStyle,
        pI = parseInt,
        dimensions = {};
        dimensions.actualWidth = pI(wGCS(el, null).width.replace('px', ''), 10);
        var newImg = document.createElement('img');
        newImg.src = src;
        newImg.style.position = 'absolute';
        newImg.style.left = '-10000px';
        document.body.appendChild(newImg);
        dimensions.originalWidth = newImg.width;
        document.body.removeChild(newImg);
        return dimensions;
    }
}

function remap(imgElem) {
    if (!imgElem) {
        return false;
    }
    else {
        var mapName = imgElem
        .getAttribute('usemap')
        .substring(1),
        map = document.getElementsByName(mapName)[0],
        areas = map.getElementsByTagName('area'),
        imgSrc = imgElem.src,
        sizes = findSizes(imgElem, imgSrc),
        currentWidth = sizes.actualWidth,
        originalWidth = sizes.originalWidth,
        multiplier = currentWidth / originalWidth,
        newCoords;

        for (var i = 0, len = areas.length; i < len; i++) {
            // Save original coordinates for future use
            var originalCoords = areas[i].getAttribute('data-original-coords');
            if (originalCoords == undefined) {
                originalCoords = areas[i].getAttribute('coords');
                areas[i].setAttribute('data-original-coords', originalCoords);
            }

            newCoords = originalCoords.replace(/(\d+)/g,function(a){
                return Math.round(a * multiplier);
            });
            areas[i].setAttribute('coords',newCoords);
        }
    }
}

function remapImage() {
    var imgElement = document.getElementsByTagName('img')[0];
    remap(imgElement);
}

// Add a window resize event listener
var addEvent = function(object, type, callback) {
    if (object == null || typeof(object) == 'undefined') return;
    if (object.addEventListener) {
        object.addEventListener(type, callback, false);
    } else if (object.attachEvent) {
        object.attachEvent("on" + type, callback);
    } else {
        object["on"+type] = callback;
    }
};

addEvent(window, "resize", remapImage);
Mihai Fratu
  • 7,579
  • 2
  • 37
  • 63
  • In this case the code would only run when the window is resized correct? Because if the image already deviates from the original size the map will not fit onto the image to begin with and a resize event would be necessary. I tried just calling remapImage(); but it didn't change anything. How could you add that behavior to your implementation? I personally added another event "load" but maybe there is a better way. –  Jul 08 '19 at 08:56