web-dev-qa-db-fra.com

Redimensionnement dynamique des images-cartes et des images

J'essaie actuellement de créer une image-carte sur mon site qui sera redimensionnée en fonction de la taille de la fenêtre ... Je me demandais s'il était possible de le faire avec HTML ou si je devais le faire avec Javascript ou un autre la langue. 

<div style="text-align:center; width:1920px; margin-left:auto; margin-right:auto;">
<img id="Image-Maps_5201211070133251" src="Site.png" usemap="#Image-Maps_5201211070133251" border="0" width="1920" height="1080" alt="" />
<map id="_Image-Maps_5201211070133251" name="Image-Maps_5201211070133251">
<area shape="poly" coords="737,116,1149,118,944,473," href="http://essper.bandcamp.com" alt="Bandcamp" title="Bandcamp"   />
<area shape="poly" coords="1006,589,1418,590,1211,945," href="http://soundcloud.com/essper" alt="Soundcloud" title="Soundcloud"   />
<area shape="poly" coords="502,590,910,591,708,944," href="http://facebook.com/the.essper" alt="Facebook" title="Facebook"   />
</map>

27
ultrazoid

Si vous vous retrouvez avec JavaScript, voici un code de codes multi-navigateurs pour redimensionner toutes les zones de l'élément MAP.

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 doit être égal à la largeur de l'image d'origine. Vous devez également utiliser des unités relatives en HTML:

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

Démo de travail à jsFiddle . Si vous ouvrez le violon dans IE, vous pouvez réellement voir AREAs lorsque vous cliquez dessus.

39
Teemu

J'ai écrit une petite petite bibliothèque pour conserver une imageMap à l'échelle en une image redimensionnable, afin que la carte reste synchronisée à mesure que l'image se redimensionne. Utile lorsque vous souhaitez mapper une image en pourcentage, etc.

Il peut être utilisé avec ou sans jQuery.

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

et vous pouvez le voir fonctionner à.

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

36
David Bradshaw

Vous pouvez multiplier les coordonnées par le rapport entre l'image d'origine et l'image stylisée. 

<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>
1
Lucas

J'ai eu le même problème la semaine dernière et j'ai fini par écrire un plugin jQuery pour cela.

Voici le projet gitHub: 

https://github.com/etienne-martin/mapify

Utilisation de base:

$("img[usemap]").mapify();

Exemple live

http://emartin.ca/mapify/

1
Etienne Martin

En classe (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);
1
Andriy Kuba

pour que cela fonctionne, vous devez avoir l'attribut data-original-coords ayant la valeur coords à l'image d'origine.

$(function () {
    function adjeustCoords() {
        var image=$('img'); //change that to your image selector
        var originalWidth=image[0].naturalWidth;
        var currentWidth=image.width();
        var ratio=currentWidth/originalWidth;
        $("map area").each(function(){
            //change that to your area selector
            var coords=$(this).attr('data-original-coords').split(',');
            coords = coords.map(function (x) {
                return Math.round(x*ratio);
                //i don't know if all browsers can accept floating point so i round the result
            });
            $(this).attr('coords',coords.join());
        });
    }
    adjeustCoords();
    $(window).resize(function(){
        adjeustCoords();
    });
});

cela fonctionne avec les versions chrome, firefox et Edge less

0
Robert

Vous pouvez utiliser des sprites CSS pour y parvenir. Vous aurez les éléments d'image s'insérer dans une seule image et de cette façon, vous ne ferez qu'une demande http pour charger toutes les images. Cette technique ne nécessite pas de javascript et vous utiliserez simplement la propriété background-position; pour déplacer vos images. 

C'est une technique efficace pour l'optimisation de la page.

0
defau1t

J'ai seulement testé cela pour les coordonnées rectangulaires, mais je pense que cela devrait généraliser à circulaire ou polygone

function wrap ( img, map ) {
  var originalCoords = [ ],
      test = new Image();

  for ( var i = 0; i < map.areas.length; ++i ) {
    var coords = map.areas[i].coords;
    originalCoords.Push( coords.split( "," ).map( parseFloat ) );
  }

  function resize () {
    var ratio = img.width / test.width;
    for ( var i = 0; i < map.areas.length; ++i ) {
      map.areas[i].coords = originalCoords[i].map( function ( n ) {
        return ratio * n;
      } ).join( "," );
    }
  }

  test.addEventListener( "load", function () {
    window.addEventListener( "resize", resize, false );
    resize();
  }, false );

  test.src = img.src;
}

var imgs = document.querySelectorAll( "img[usemap]" );
for ( var i = 0; i < imgs.length; ++i ) {
  var map = document.querySelector( "map[name=" + imgs[i].useMap.substring( 1 ) + "]" );
  wrap( imgs[i], map );
}
0
moron4hire

Si vous avez accès à Illustrator ou à un autre programme pouvant générer un fichier SVG , il est très facile de créer une carte-image dynamique avec un fichier SVG.

Ceci ne nécessite aucune programmation.

Voici les instructions pour Illustrator _ ​​(ne prend que quelques secondes) :

  1. ouvrir l'image dans Illustrator, enregistrer sous un nouveau nom

  2. redimensionner le document à la même taille que l'image

  3. dessiner des rectangles remplis pour les parties de la carte (utile pour mettre l'opacité à 50%)

  4. en utilisant la palette "Attributs", ajoutez un lien vers chaque rectangle

  5. changer l'opacité de tous les rectangles à 0%

  6. sélectionnez l'image et dans le menu de la palette "liens" sélectionnez "Unembed…" (le nom importe peu, nous n'utiliserons pas l'image)

  7. file ›save as SVG (emplacement de l'image: lien, propriétés CSS: style éléments, réactif est coché)

  8. ouvrez le fichier svg résultant

  9. supprimer les deux premières lignes (XML & commentaire Adobe)

  10. mettre à jour la source de l'image

  11. collez le code svg dans votre document html

Cela fonctionne dans tous les principaux navigateurs. Voici une capture d'écran des paramètres d'exportation SVG pour Illustrator:

 enter image description here

0
Andrew Swift

Voici un autre plugin que je viens d'écrire pour gérer les cartes-images: https://github.com/gestixi/pictarea

Entre autres choses, les zones s’échelonnent automatiquement en fonction de la taille de l’image. Notez qu'il utilise canvas pour rendre les zones.

Utilisation de base:

$(function() {
  $('#map').pictarea({
    rescaleOnResize: true
  });
});
0
Nicolas BADIA