Image Maps

back to the roots…

Henning über Webdesign

Von Zeit zu Zeit kommt man an den Punkt an dem man auch mal einen antiquierten Task ausführen muss – wie z.B. das Anlegen und Bearbeiten einer Image Map. Als wäre das nicht schon genug wurde noch gewünscht einen Marker nach dem Motto „Sie sind hier“ auf der Image Map zu positionieren.

Die besagte Image Map basiert nur auf Rectangles, es sind daher keine komplexen jQuery-Plugins notwendig, um diesen Task zu erfüllen. In nachfolgendem Beispiel habe ich auf die Schnelle mal eine Image Map gescribbled. Hier der HTML Code:

<map id="map" name="map">
	<area alt="1st Rectangle" coords="0, 0, 100, 100"   href="#1" shape="rect">
	<area alt="2nd Rectangle" coords="118, 11, 197, 89" href="#2" shape="rect">
	<area alt="3rd Rectangle" coords="215, 21, 273, 79" href="#3" shape="rect">
</map>
<img alt="map" id="mapimg" height="100" src="imgmap.png" usemap="#map" width="300">

Der „Sie sind hier“-Marker soll ein kleiner roter Kreis sein. Hierzu bietet sich ein div an, dem wir den folgenden Style zuweisen:

map > div#marker {    
		    background-color: red;
		    border: 2px solid red;
		    border-radius: 50%;
		    opacity: .8;
		    z-index: 100;
		 }

Der z-index wird auf einen Wert oberhalb des Indexes unserer Map gelegt, ich verwende hier 100 (wobei 1 schon genügen würde- aber sicher ist sicher).

Was soll unser JavaScript tun? Wenn der Benutzer auf einen Hotspot klickt, soll das kleine Script besagten roten Punkt in der Mitte des ausgewählten Rectangles positionieren. Dazu müssen wir uns zuerst ​einen Überblick über die Gegebenheiten verschaffen – Ausmaße des Bildes, Koordinaten der Hotspots. Das lässt sich wie folgt bewerkstelligen:

//get the source image
var id = $(this).parent().attr("id"),
    query = "img[usemap=#" + id + "]",
    img = $.find(query);

//get the image boundaries
var offset = $(img).offset();
var markerWidth = 20, 
    elem = offset[0],
    pos = { width:img.offsetWidth, height:img.offsetHeight, x: 0, y: 0 };

    pos.x = offset.left; 
    pos.y = offset.top;

Zuerst liest man das Source-Image aus der Image Map aus. Man lässt sich die Id der Image Map geben und sucht nach einem Bild mit dem usemap-Attribut und gleichlautendem Attributwert. Das gefundene Objekt ist unser Bild. Mit offset() kann man sich die Ausmaße des Bildes geben lassen und wie in diesem Falle z.B. in einem Objekt (pos) speichern.

Jetzt werden die Koordinaten der Image Map-Hotspots ausgelesen. Der nachfolgende Code ermittelt die Koordinaten der angeklickten area.

//get the coords
var $this = $(this);
var coords = $this.attr("coords").split(',');

//get the coors as intager
var x1 = parseInt(coords[0],10),
    y1 = parseInt(coords[1],10),
    x2 = parseInt(coords[2],10),
    y2 = parseInt(coords[3],10);

Nachdem diese bekannt sind, muss ein klein wenig Mathe angewandt werden um die Position des Markers zu ermitteln. Zuerst werden top– und left-Position des Hotspots innerhalb des Bildes ermittelt. Anschließend kann man mittels einfacher Formeln die left– und die top-Position des Markers bestimmen:

  • left: x des Hotspots + halbe Breite des Hotspots – Radius des Markers
  • top: y-Position des Hotspots + halbe Höhe des Hotspots – Radius des Markers

Anschließend wird das generierte div an die Image Map angehängt.

//set the marker position
var markerX1 = pos.x + x1;
var markerY1 = pos.y + y1;
var markerRadius = markerWidth/2;

//create the dom element and apply some css
//formula: marker y + half height rectangle - half height marker
//formular: marker x + half width rectangle - half width marker
var div = $("<div id='marker'>");
div.css({				
             'position': 'absolute'
	    , top: markerY1 + (y2 - y1)/2  - markerRadius
            , left: markerX1 + (x2 - x1)/2 - markerRadius
            , width:  markerWidth
            , height: markerWidth
	});
//append the newly created element	
$("#map").append(div);

Jetzt noch etwas notwendige Kosmetik wie z.B. bei einem Klick zuerst alle Marker zu entfernen, damit jeweils nur ein Marker auf der Map zu sehen ist. Und das war’s schon. Hier noch einmal das Script in voller Länge:

$("#map area").on("click", function() {

//clear all markers
$("#marker").remove();

//get the source image
var id = $(this).parent().attr("id"),
    query = "img[usemap=#" + id + "]",
    img = $.find(query);

//get the image boundaries
var offset = $(img).offset();
var markerWidth = 20, 
    elem = offset[0],
    pos = { width:img.offsetWidth, height:img.offsetHeight, x: 0, y: 0 };

    pos.x = offset.left; 
    pos.y = offset.top;

//get the coords
var $this = $(this);
var coords = $this.attr("coords").split(',');

//get the coors as intager
var x1 = parseInt(coords[0],10),
    y1 = parseInt(coords[1],10),
    x2 = parseInt(coords[2],10),
    y2 = parseInt(coords[3],10);

//set the marker position
var markerX1 = pos.x + x1;
var markerY1 = pos.y + y1;
var markerRadius = markerWidth/2;

//create the dom element and apply some css
//formula: marker y + half height rectangle - half height marker
//formular: marker x + half width rectangle - half width marker
var div = $("<div id='marker'>");
div.css({				
             'position': 'absolute'
	    , top: markerY1 + (y2 - y1)/2  - markerRadius
            , left: markerX1 + (x2 - x1)/2 - markerRadius
            , width:  markerWidth
            , height: markerWidth
	});
//append the newly created element	
$("#map").append(div);

});

Informationen über den Autor

Henning

...ist ein User Interface und User Experience Designer. Nebenbei Frontend Developer für Web-, Desktop- und mobile Plattformen. Mit mehr als 10 Jahren professioneller Projekterfahrung schreibt er zu den Themen Webdesign, -trends und -programmierung – eben fullstack! Follow @kingfries