javascript rubberband zoom box

Doug Williams williams at WEBSAWYER.COM
Thu Mar 2 02:57:50 EST 2006


I guess I've 'borrowed' enough code that I can share some.

Below are the pieces for implementing a rubberband zoom box using only
client-side javascript.  The way I use this I can zoom to the extent defined
by the box, or I can jsut click on the map to zoom to a point.  I don't think
it would be hard to modify to give distance measurements, if that is what was
desired.  Feel free to contact me if you have any questions.
Sorry for the formatting.

I use these spans to display the x,y coords as the mouse moves over the map.
Stick them somewhere you might want to see this info.
<span style="font-size:6pt;" id=latspan name=latspan></span>-<span
style="font-size:6pt;" id=lonspan name=lonspan></span>
<span style="font-size:6pt;" id=x1 name=x1></span>-<span
style="font-size:6pt;" id=y1 name=y1></span>: 
<span style="font-size:6pt;" id=x2 name=x2></span>-<span
style="font-size:6pt;" id=y2 name=y2></span> 


These two divs replace the <input type=image ...> that typically holds the map.
The <input type=image...> is crippling... forcing form submission and only
giving one x,y pair. So...
The first div holds the map, the second one is a layer for drawing the
rubberband zoom box on.
Note the "positioning" of the div elements, the second div positioned
absolutely inside the first.

        <div
style="position:relative;border:0px;height:300px;width:600;border-style:none;background-image:url(<?php
echo $image_url?>);"><img src="<?php echo $image_url?>">
        <div id=drawdiv name=drawdiv onmousemove="getMouseXY(event);"
onmousedown="setMouseXY(event,'x1','y1');"
onmouseup="setMouseXY(event,'x2','y2');document.mapserv.submit();" 
style="position:absolute;top:0px;left:0;height:300px;width:600;border:0px;"></div></div>

The mouse events drive the scripts below to display the coords and draw the
zoom box.  I submit the form on mouseup, but it does not have to be submitted
if that was not wanted.


  <script language=javascript>

//////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////

// this stuff on drawing lines I modified from what I found here:
//                http://www.thescripts.com/forum/thread88771.html
// I commented out stuff that was bogus or unnecessary for my purpose.

function DrawLinHor( x, y, size, color, div2){
  var str;
  if (x>=0 && y>=0 && size>0){
    str = '<div style="position:absolute; left:' + x + 'px; top:' + y +
'px;width:' + size + 'px; height:1px;background-color:' + color + '"><table
height=1 width=' + size + '></table></div>\n';
  } else {
    str = '';
  }
//  document.write(str);
  document.getElementById(div2).innerHTML += str;
}

function DrawLinVert( x, y, size, color, div2){
  var str;
  if (x>=0 && y>=0 && size>0){
    str = '<div style="position:absolute; left:' + x + 'px; top:' + y +
'px;width:1px; height:' + size + 'px;background-color:' + color + '"><table
height=' + size + ' width=1></table></div>\n';
  } else {
  str = '';
  }
//  document.write(str);
  document.getElementById(div2).innerHTML += str;
}

function DrawLine( x1, y1, x2, y2, color, div2 ){
  deltax=x2-x1;
  deltay=y2-y1;
  if (deltax>=deltay){
//    if (y2<y1) {
//      help=x1;
//      x1=x2;
//      x2=help;
//      help=y1;
//      y1=y2;
//      y2=help;
//    }

//    deltax=x2-x1;
//    deltay=y2-y1;
    dstep=deltax/(deltay+1);
//    dstep=deltax;
//window.alert('step: ' + dstep);

    x=x1;
    y=y1; // i added this

//    if (dstep<0){
//      x=x+dstep;
//    }

//    for (y=y1;y<=y2;y++){
//      size=((x+dstep)-(x));  // for instance, note that (x + y) - (x) = x +
y - x = x - x + y = y
                               // so what's that all about except to be confusing!
//      if (dstep<0) {
//        DrawLinHor( (x)-(dstep)+(size),(y),Math.abs(size),color,div2 );
//      } else {
////        DrawLinHor( (x),(y),Math.abs(size),color,div2 );
        DrawLinHor( (x),(y),dstep,color,div2 );
//      }
//      x=x+dstep;
//    }
  } else {
//    if (x2<x1) {
//      help=x1;
//      x1=x2;
//      x2=help;
//      help=y1;
//      y1=y2;
//      y2=help;
//    }

//    deltax=x2-x1;
//    deltay=y2-y1;
    dstep=deltay/(deltax+1);
//    dstep=deltay;

    y=y1;
    x=x1; // i added this
//    if (dstep<0){
//      y=y+dstep;
//    }

//    for (x=x1;x<=x2;x++){
//      size=((y+dstep)-(y))
//      if (dstep<0){
//        DrawLinVert( (x),(y)-(dstep)+(size),Math.abs(size),color,div2 );
//      } else {
////        DrawLinVert( (x),(y),Math.abs(size),color,div2 );
        DrawLinVert( (x),(y),dstep,color,div2 );
//      }
//      y=y+dstep;
//    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////



var mouseIsDown = false
var tmpX1
var tmpY1
var tmpX2
var tmpY2


// this stuff on getting the x,y coordinates I modified from what I found here:
//         http://www.codelifter.com/main/javascript/capturemouseposition1.html

var IE = document.all?true:false
// If NS -- that is, !IE -- then set up for mouse capture
if (!IE) document.captureEvents(Event.MOUSEMOVE || Event.MOUSEUP ||
Event.MOUSEDOWN)

function getMouseXY(e) {
var tempX = 0
var tempY = 0
  if (IE) { // grab the x-y pos.s if browser is IE
//    tempX = event.clientX + document.body.scrollLeft // they got x,y based
on whole window! 
//    tempY = event.clientY + document.body.scrollTop
    tempX = event.offsetX  // i get x,y based on div layer!!
    tempY = event.offsetY
  } else {  // grab the x-y pos.s if browser is NS
//    tempX = e.pageX
//    tempY = e.pageY
    tempX = e.layerX
    tempY = e.layerY
  }
if (!((tempX == 0) || (tempY == 0))) {  
  // catch possible negative values in NS4
  if (tempX < 0){tempX = 0}
  if (tempY < 0){tempY = 0}  
  // show the position values in the form named Show
  // in the text fields named MouseX and MouseY
  document.getElementById('lonspan').innerHTML = tempX
  document.getElementById('latspan').innerHTML = tempY


  if (mouseIsDown) {
    document.mapserv.img_x2.value = tempX
    document.mapserv.img_y2.value = tempY
    // i set x2,y2 here because setting on the mouseup was unreliable
    // sometimes the tempX,tempY seems to be relative to the last coord where
the mouse changed direction!
    document.getElementById('x2').innerHTML = tempX
    document.getElementById('y2').innerHTML = tempY

    document.getElementById('drawdiv').innerHTML = '';
    if (document.mapserv.img_x1.value > tempX) {
       tmpX1 = tempX
       tmpX2 = document.mapserv.img_x1.value
    }else{
      tmpX1 = document.mapserv.img_x1.value
      tmpX2 = tempX
    }

    if (document.mapserv.img_y1.value > tempY) {
      tmpY1 = tempY
      tmpY2 = document.mapserv.img_y1.value
    }else{
      tmpY1 = document.mapserv.img_y1.value
      tmpY2 = tempY
    }



//window.alert(tmpX1 + ',' + tmpY1 + '   :   ' + tmpX2 + ',' + tmpY2)
 if ((tmpY1 > 0) && (tmpX1 > 0) && (tmpY2 > 0) && (tmpX2 > 0)) {  // this
avoids the cases where tempX and tempY seem to be relative to the last coord
where mouse changed direction - those coords don't draw well!

//window.alert(tmpX1 + ',' + tmpY1 + '   :   ' + tmpX2 + ',' + tmpY2)
    DrawLine(tmpX1,tmpY1,tmpX1,tmpY2,"#FF0000","drawdiv");
    DrawLine(tmpX1,tmpY1,tmpX2,tmpY1,"#FF0000","drawdiv");
    DrawLine(tmpX2,tmpY1,tmpX2,tmpY2,"#FF0000","drawdiv");
    DrawLine(tmpX1,tmpY2,tmpX2,tmpY2,"#FF0000","drawdiv");
 }
  }
}

  return true
}


function setMouseXY(e,x,y) {  
  var tempX
  var tempY

  if (x == 'x2') mouseIsDown = false
  if (IE) { // grab the x-y pos.s if browser is IE
//    tempX = event.clientX + document.body.scrollLeft
//    tempY = event.clientY + document.body.scrollTop
    tempX = event.offsetX
    tempY = event.offsetY
  } else {  // grab the x-y pos.s if browser is NS
//    tempX = e.pageX
//    tempY = e.pageY
    tempX = e.layerX
    tempY = e.layerY
  }  
  // catch possible negative values in NS4
  if (tempX < 0){tempX = 0}
  if (tempY < 0){tempY = 0}  
  // show the position values in the form named Show
  // in the text fields named MouseX and MouseY
  if (y == "y1") {  // mousedown
    document.getElementById(x).innerHTML = tempX
    document.getElementById(y).innerHTML = tempY
    document.mapserv.img_x.value = tempX
    document.mapserv.img_y.value = tempY
    document.mapserv.img_x1.value = tempX
    document.mapserv.img_y1.value = tempY
  }
  if (y == "y2") {  // mouseup
    if ((tempX == document.mapserv.img_x1.value) && (tempY ==
document.mapserv.img_y1.value)) {
      document.mapserv.img_x2.value = ''
      document.mapserv.img_y2.value = ''
    }else{
      if (document.mapserv.img_x2.value < document.mapserv.img_x1.value) {
        tempX = document.mapserv.img_x1.value
        document.mapserv.img_x1.value = document.mapserv.img_x2.value
        document.mapserv.img_x2.value = tempX
      }
      if (document.mapserv.img_y2.value < document.mapserv.img_y1.value) {
        tempY = document.mapserv.img_y1.value
        document.mapserv.img_y1.value = document.mapserv.img_y2.value
        document.mapserv.img_y2.value = tempY
      }
    }
  }
  if (x == 'x1') {
    mouseIsDown = true
  }
  return true
}



  </script>

////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////

I found the following web pages interesting...

    http://evolt.org/article/Mission_Impossible_mouse_position/17/23335/index.html

    http://www.quirksmode.org/



More information about the mapserver-users mailing list