SiteExperts.com Logo Home | Community | Developer's Paradise | Jobs
User Groups | Site Tools | Site Information | Search

Inside Technique : Targeted Drag and Drop : Collision Detection Algorithm

Collision Detection is a commonly used technique in interactive arcade games. It is used to detect whether two or more elements in the game have bumped into each other, for example the monsters bumping into PacMan. We will use a similar technique to check whether our floating DIV is touching or overlapping a valid Drag Target.

The reason we need this algorithm is that since the mouse is over the floating DIV, the onmouseup event's srcElement will not be accurate. Also, since the surface area of the floating DIV is quite large, it is quite possible that the DIV may overlap two or more potential targets. Only by comparing the area of overlap of each target, can we accurately determine which was the target the user intended. Happily, the Collision Detection Algorithm can do this.

The algorithm goes something like this -

Given 2 rectangular objects of the same size, 
the Horizontal and Vertical overlap between
them is given by :
hOverlap = W - |x2-x1|
vOverlap = H - |y2-y1|

where
W=width of the objects
H=Height of the objects
x1,y1=Top Left co-ordinates of Obj 1
x2,y2=Top Left co-ordinates of Obj 2

if both hOverlap and vOverlap are positive
their product gives the area of overlap of
the 2 objects.
if either or both are negative, the objects
do not overlap (have not collided).

*** Algorithm devised by Stanley Rajasingh *** 

Now that we have the algorithm, coding the onmouseup handler is a trivial exercise. Looking at it we see -

function DragEnd(){
  if(!DragEl) return;
  X1=floater.style.pixelLeft;
  Y1=floater.style.pixelTop;
  MaxArea=0;
  TargetElem=null;

  Targets=document.all;
  for(i=0;i<Targets.length;i++)
    if(Targets[i].className=="dnd"){
      X2=getRealPos(Targets[i].children[0],"Left");
      Y2=getRealPos(Targets[i].children[0],"Top");
      hOverlap=floater.offsetWidth-Math.abs(X2-X1);
      vOverlap=floater.offsetHeight-Math.abs(Y2-Y1);
      areaOverlap=((hOverlap>0)&&(vOverlap>0))?hOverlap*vOverlap:0;
      if(areaOverlap>MaxArea){ 
        MaxArea=areaOverlap;
        TargetElem=Targets[i];
      }
    }
	
  floater.style.visibility='hidden';

  if(TargetElem){
    //Swap Images
    DragEl.src=TargetElem.children[0].src;
    TargetElem.children[0].src=floater.children[0].src;
  } else {
    //Restore Original Image
    DragEl.src=floater.children[0].src;
    return;
  }
  DragEl=null;
}

The big for loop cycles through each element in the document, checking to see if it is a valid Drag Target (className=="dnd"). If it is, the code applies the Collision Detection Algorithm to obtain the overlap area. The element which has the largest overlap with the floating DIV becomes the TargetElem.

Once the target has been obtained, the function swaps the source and target images, and then hides the floating DIV, creating the illusion that the Drag Source and Drag Target have exchanged places. Finally it resets the Drag Source pointer (DragEl) to null, indicating that the dragging has ended.

That's it for targeted drag and drop. You should be aware that since this algorithm takes over the onmouseover, onmouseup, and onmousemove handlers of the document, any other element on the page that uses these events, such as a DHTML menu, will not function. In order to prevent this you might want to overload these handlers rather than taking over them entirely. I have discussed function overloading in a previous article, Creating Solitaire Games. You can also check out other cool user interfaces in SiteExperts' vast Tasks section.

Discuss and Rate this Article

Page 1:Targeted Drag and Drop
Page 2:Hot Tracking
Page 3:Setting up the Drag
Page 4:Collision Detection Algorithm