jQuery/JavaScript collision detection

前端 未结 7 2152
情话喂你
情话喂你 2020-11-22 04:49

How to detect if two

elements have collided?

The two divs are simple coloured boxes travelling perpendicular to each other, so no complicate

7条回答
  •  长情又很酷
    2020-11-22 05:35

    Its a little late on this but I guess you could use this approach that I tried when I was faced with the similar situation. The advantage here is that there are no additional plugin, or scripts involved and neither do you have to introduce performance hungry polling into it. This technique uses the the built-in methods and events that Jquery's droppable has to offer.

    Ok, enough said, here's the solution technique: Say if you have two elements (images in my case) and you don't want them to overlap or detect when they do, make the two elements a droppable and make them to 'accept' each other:

    $([div1, div2]).droppable(CONFIG_COLLISSION_PREVENTION_DROPPABLE);
    

    The 'CONFIG_COLLISSION_PREVENTION_DROPPABLE' looks like this:

    var originatingOffset = null;
    CONFIG_COLLISSION_PREVENTION_DROPPABLE = {
        tolerance: "touch",
        activate : function (event, ui) {
            // note the initial position/offset when drag starts
            // will be usedful in drop handler to check if the move
            // occurred and in cae overlap occurred, restore the original positions.
            originatingOffset = ui.offset;
        },
        drop : function (event, ui) {
                // If this callback gets invoked, the overlap has occurred. 
                // Use this method to either generate a custom event etc.
    
                // Here, i used it to nullify the move and resetting the dragged element's 
                // position back to it's original position/offset
                // (which was captured in the 'activate' handler)
            $(ui.draggable).animate({
                top: originatingOffset.top + "px",
                left: originatingOffset.left + "px"
            }, 300);
         }
    }
    

    The 'activate' and 'drop' handlers refer to the 'dropactivate' and 'drop' events of "droppable" plugin

    Here, the key is the 'drop' callback. Whenever any of the two elements overlap and they are dropped over each other, the 'drop' will be called. This is the place to detect and take actions, may be sending out custom events or calling other actions (I here chose to revert the overlapping element's positions to the initial position when the drag started, which was captured in 'activate' callback).

    That's it. No polling, no plugins, just the built-in events.

    Well, there can be other optimizations/extensions done to it, this was simply the first shot out of my head that worked :)

    You can also use the 'dropover' and 'dropout' events to signal and create a visual feedback to the user that two elements are overlapping, while they may be still on the move.

    var CLASS_INVALID = "invalid";
    // .invalid { border: 1px solid red; }
    ...
    $.extend(CONFIG_COLLISSION_PREVENTION_DROPPABLE, {
       over : function (event, ui) {
            // When an element is over another, it gets detected here;
            // while it may still be moved.
            // the draggable element becomes 'invalid' and so apply the class here
            $(ui.draggable).addClass(CLASS_INVALID);
        },
        out : function(event, ui) {               
             // the element has exited the overlapped droppable now
             // So element is valid now and so remove the invalid class from it
             $(ui.draggable).removeClass(CLASS_INVALID);
        }
    });
    

    Hope this helps!

提交回复
热议问题