Collision detection on more than 2 divs with jQuery draggable?

Here is the fiddle;

http://jsfiddle.net/dh4qysej/

I want to do this with dynamically created elements, so divs don't exist yet when the function is called.

I would like to try to work out a solution that could cover x the number of divs and process it with minimal code, but making a patchwork version to accommodate three divs seems to be the logical first step before figuring out a way to cover even more.

I figured I would have to specify if-else if in order to detect calculations across all variables, however, this doesn't seem to work. I was hoping someone could point me in the right direction?

Thanks in advance - the code below (works between the first two divs);

function collision($div1, $div2, $div3) { if ($div1.length > 0) { var x1 = $div1.offset().left; var y1 = $div1.offset().top; var h1 = $div1.outerHeight(true); var w1 = $div1.outerWidth(true); var b1 = y1 + h1; var r1 = x1 + w1; } if ($div2.length > 0) { var x2 = $div2.offset().left; var y2 = $div2.offset().top; var h2 = $div2.outerHeight(true); var w2 = $div2.outerWidth(true); var b2 = y2 + h2; var r2 = x2 + w2; } if ($div3.length > 0) { var x3 = $div3.offset().left; var y3 = $div3.offset().top; var h3 = $div3.outerHeight(true); var w3 = $div3.outerWidth(true); var b3 = y3 + h3; var r3 = x3 + w3; } if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) { return false; } else { return true; } } onmousemove = function(e) { $('#result').text(collision($('#div1'), $('#div2'), $("#div3"))); }; $('#div1,#div2, #div3').draggable(); 
 #div1 { width: 200px; height: 50px; background-color: pink; } #div2 { width: 200px; height: 50px; background-color: green; } #div3 { width: 200px; height: 50px; background-color: red; } 
 <strong>Drag divs around.</strong> <div id="div1"> Div1 </div> <br/> <div id="div2"> Div2 </div> <br> <div id="div3"> Div3 </div> <p>Colliding? <span id="result">false</span> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script> 
+5
source share
1 answer
  • First, instead of using id to bind events, use the class selector.
  • Use the flag to check if the user is currently dragging any draggable item.
  • Scroll all draggable items and experience a collision with respect to the current draggable item.

 function collision(draggableItems) { return draggableItems .toArray() .reduce(function(isColliding, currNode){ if(isColliding){return isColliding;} var $currNode = $(currNode); var x1 = $currNode.offset().left; var y1 = $currNode.offset().top; var h1 = $currNode.outerHeight(true); var w1 = $currNode.outerWidth(true); var b1 = y1 + h1; var r1 = x1 + w1; draggableItems.each(function(index, node){ if(node == currNode || isColliding){ return; } var $node = $(node); var x2 = $node.offset().left; var y2 = $node.offset().top; var h2 = $node.outerHeight(true); var w2 = $node.outerWidth(true); var b2 = y2 + h1; var r2 = x2 + w1; if(!(b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2)){ isColliding = true; } }); return isColliding; }, false); } var isDragging = false; $('.draggableItem') .on('mousedown', function(e){ isDragging = true; }) .on('mousemove',function(e) { if(!isDragging){return;} $('#result').text(collision($('.draggableItem'))); }) .on('mouseup', function(e){ isDragging = false; }); $('.draggableItem').draggable(); 
 #div1 { width: 200px; height: 50px; background-color: pink; } #div2 { width: 200px; height: 50px; background-color: green; } #div3 { width: 200px; height: 50px; background-color: red; } 
 <strong>Drag divs around.</strong> <div id="div1" class="draggableItem"> Div1 </div> <br/> <div id="div2" class="draggableItem"> Div2 </div> <br> <div id="div3" class="draggableItem"> Div3 </div> <p>Colliding? <span id="result">false</span> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script> 
+2
source

All Articles