I have latelly been wondering how to make a responsive image map. Sounds impossible, but I did find a way to do it http://home.comcast.net/~urbanjost/IMG/resizeimg.html
If you look at the source, you can see everything. This has no attached JQuery or Ruby, or whatever plugins people recomend to do this.
However, when I tried implementing this JS to my code, it just didn't work. I've been searching day and night but can't find a thing.
Here is the original code:
JS:
GLOBAL_COUNT = 0;
GLOBAL_AREAS = new Array();
GLOBAL_WIDTH = 1;
function scaleXY(elementid, scale) {
// avoid problems with 0 scales and image becoming so small it does not change size
// I think something breaks in firefox(1) when you shrink so much that all values in an coords= become 0
// I think something breaks in iexplore(1) when you shrink so much that all values in an coords= become 0
myscale = Math.max(0, scale);
oldwidth = document.getElementById(elementid).width
oldheight = document.getElementById(elementid).height
newwidth = Math.round(Math.max(oldwidth * myscale, 1));
newheight = Math.round(Math.max(oldheight * myscale, 1));
if(oldwidth == newwidth) newwidth =+ 1;
if(oldheight == newheight) newheight =+ 1;
document.getElementById(elementid).width = newwidth;
document.getElementById(elementid).height = newheight;
scaleArea();
}
// Assuming one image map in document.
// Assuming coordinates are comma-delimited in AREA COORDS= string.
// Assuming the same zoom factor for the height as for the width of the image.
function getglobal() { // place original AREA coordinate strings into a global array, called at load
var arrayAreas = document.body.getElementsByTagName("AREA");
GLOBAL_WIDTH = document.getElementById("myimage").width; // get original width
for(var i = 0; i < arrayAreas.length; i++) {
GLOBAL_AREAS[i]= arrayAreas[i].coords;
}
GLOBAL_COUNT++;
}
function scaleArea() { // using values stored at load, recalculate new values for the current size
var arrayAreas = document.body.getElementsByTagName("AREA");
for(var i = 0; i < arrayAreas.length; i++) {
ii = i+1;
rescale = document.getElementById("myimage").width/GLOBAL_WIDTH ;
sarray = GLOBAL_AREAS[i].split(","); // convert coordinates to a numeric array assuming comma-delimited values
var rarray =new Array();
for(var j = 0; j < sarray.length; j++) {
rarray[j] = parseInt(sarray[j])*rescale; // rescale the values
rarray[j] = Math.round(rarray[j]);
} //alert( "GLOBAL " + GLOBAL_AREAS[i] + ":" + sarray.length + " SPLIT=" + sarray +rarray.length);
arrayAreas[i].coords = rarray.join(","); // put the values back into a string
}
showArea();
}
HTML:
<body onload="getglobal();" >
<form>
<input type="button" onclick="scaleXY('myimage',1.0/1.13);" value="scaled smaller" />
<input type="button" onclick="scaleXY('myimage',1.13);" value="scaled bigger" />
</form>
<div>
<img id="myimage" src="hcopy.gif" alt="Round buttons" usemap="#circles" height="839" width="586" />
<map id="circles" name="circles" >
<area target="_blank" title="CYAN AREA" alt="CYAN" shape="circle" coords="50,50,20" href="#CYAN" />
<area target="_blank" title="BLUE AREA" alt="BLUE" shape="circle" coords="25,25,20" href="#BLUE" />
<area target="_blank" title="RED AREA" alt="RED" shape="circle" coords="25,75,20" href="#RED" />
<area target="_blank" title="MAGENTA AREA" alt="MAGENTA" shape="circle" coords="75,25,20" href="#MAGENTA" />
<area target="_blank" title="GREEN AREA" alt="GREEN" shape="circle" coords="75,75,20" href="#GREEN" />
<area target="_blank" title="YELLOW AREA" alt="YELLOW" shape="rect" coords="0,0,100,100" href="#YELLOW" />
</map>
</div>
<body>
Again, I didn't make this code. I have trouble understanding it. But the biggest problem comes when I try implementing this code to my image, then, it stopes working.
The code:
HTML:
<form onload="getglobal()">
<input type="button" onclick="scaleImageDown()" value="scaled smaller" />
<input type="button" onclick="scaleImageUp()" value="scaled bigger" />
</form>
<div>
<img src="http://www.astro-galaxy.com/sys_files/sys_view/CL1296246121697.jpg" usemap="#circles" id="myimage" width="839" height"586" >
<map name="circles" id="circles">
<area shape="circle" coords="-264,320,442" href="" title="Sun">
<area shape="circle" coords="244,79,13" href="" title="Mercury">
<area shape="circle" coords="307,122,24" href="" title="Venus">
<area shape="circle" coords="382,187,29" href="" title="Earth">
<area shape="circle" coords="414,149,14" href="" title="The Moon">
<area shape="circle" coords="432,232,16" href="" title="Mars">
<area shape="circle" coords="408,249,8" href="" title="Deimos">
<area shape="circle" coords="456,217,8" href="" title="Phobos">
<area shape="rect" coords="413,261,486,292" href="" title="Asteroids">
<area shape="circle" coords="563,337,85" href="" title="Jupiter">
<area shape="circle" coords="430,421,14" href="" title="Europa">
<area shape="circle" coords="463,395,18" href="" title="Ganymede">
<area shape="circle" coords="653,245,17" href="" title="Callisto">
<area shape="circle" coords="690,220,13" href="" title="Io">
<area shape="circle" coords="668,431,41" href="" title="Saturn">
<area shape="circle" coords="727,397,11" href="" title="Titan">
<area shape="circle" coords="734,487,21" href="" title="Uranus">
<area shape="circle" coords="684,525,10" href="" title="Umbriel">
<area shape="circle" coords="702,512,10" href="" title="Miranda">
<area shape="circle" coords="769,460,10" href="" title="Ariel">
<area shape="circle" coords="785,445,10" href="" title="Titania">
<area shape="circle" coords="802,430,10" href="" title="Oberon">
<area shape="circle" coords="784,536,27" href="" title="Neptune">
<area shape="circle" coords="757,565,10" href="" title="Triton">
<area shape="circle" coords="816,574,10" href="" title="Pluto">
</map>
</div>
JS:
GLOBAL_COUNT = 0;
GLOBAL_AREAS = new Array();
GLOBAL_WIDTH = 1;
eid = "myimage";
function scaleImageDown() {
// avoid problems with 0 scales and image becoming so small it does not change size
// I think something breaks in firefox(1) when you shrink so much that all values in an coords= become 0
// I think something breaks in iexplore(1) when you shrink so much that all values in an coords= become 0
var myscale = 0.5;
var oldwidth = document.getElementById(eid).width;
var oldheight = document.getElementById(eid).height;
var newwidth = oldwidth * myscale;
var newheight = oldheight * myscale;
if(oldwidth == newwidth) {
newwidth =+ 1
}
if(oldheight == newheight) {
newheight =+ 1
}
document.getElementById(eid).width = newwidth;
document.getElementById(eid).height = newheight;
scaleArea();
}
function scaleImageUp() {
var myscale = 2;
var oldwidth = document.getElementById(eid).width;
var oldheight = document.getElementById(eid).height;
var newwidth = oldwidth * myscale;
var newheight = oldheight * myscale;
if(oldwidth == newwidth) {
newwidth =+ 1
}
if(oldheight == newheight) {
newheight =+ 1
}
document.getElementById(eid).width = newwidth;
document.getElementById(eid).height = newheight;
scaleArea();
}
// Assuming one image map in document.
// Assuming coordinates are comma-delimited in AREA COORDS= string.
// Assuming the same zoom factor for the height as for the width of the image.
function getglobal(){ // place original AREA coordinate strings into a global array, called at load
var arrayAreas = document.body.getElementsByTagName("area");
GLOBAL_WIDTH = document.getElementById(eid).width; // get original width
for(var i = 0; i < arrayAreas.length; i++) {
GLOBAL_AREAS[i]= arrayAreas[i].coords;
}
GLOBAL_COUNT++;
}
function scaleArea() { // using values stored at load, recalculate new values for the current size
var arrayAreas = document.body.getElementsByTagName("area");
for(var i = 0; i < arrayAreas.length; i++) {
var ii = i + 1;
var rescale = document.getElementById(eid).width/GLOBAL_WIDTH ;
var sarray = GLOBAL_AREAS[i].split(","); // convert coordinates to a numeric array assuming comma-delimited values
var rarray = new Array();
for(var j = 0; j < sarray.length; j++) {
rarray[j] = parseInt(sarray[j]) * rescale; // rescale the values
rarray[j] = Math.round(rarray[j]);
} //alert( "GLOBAL " + GLOBAL_AREAS[i] + ":" + sarray.length + " SPLIT=" + sarray +rarray.length);
arrayAreas[i].coords=rarray.join(","); // put the values back into a string
}
showArea();
}
As you can see, they are pretty much the same. The only difference is that the top onw works, and the bottom one doesn't. Please help. And thank you for any explanation of how it works(Other than the basics, of course). Thanx!
A <form>
element doesn't have a naturally occurring 'load' event, therefore getglobal()
is not called in your version of the code.
Try reinstating <body onload="getglobal();">
Alternatively, find some other way to cause getglobal()
to be called - eg in response to some user event.
First, the HTML causes the DOM to be populated with :
<form>
element containing two buttons<img>
element<map>
element containing a number of areasThe document's <body>
element has getglobal()
attached to it as its onload handler, which causes several global variables to be set :
GLOBAL_WIDTH
: the <img>
element's initial width.GLOBAL_AREAS
: an array of the image map's initial area coords, "-264,320,442" etc.GLOBAL_COUNT
: which is set but not used.By setting these global vars once, there's a lot less to do every time the image and its map are rescaled.
The two form buttons are each given a 'click' action by attaching onclick handlers :
The two functions scaleImageDown()
and scaleImageUp()
:
GLOBAL_AREAS
array and manipulate the area nodes' coords
attribute such that each of the coordinates is either divided or multiplied by 2. This has the desired effect of rescaling the entire map.The utility function scaleArea()
exists to avoid repetition of code in scaleImageDown()
and scaleImageUp()
.