detect collision

a simple testfor collision detection with jQuery and DOM elements

by Craig Martin

HTML

<div id="element"></div>

<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>

<div class="explanation">Give the focus to this window and use arrow to move the red ball</div>

CSS

#element{
    position: absolute;
    top: 100px;
    left: 100px;
    width: 50px;
    height: 50px;
    background: red;
    border-radius: 50px;
}
.block{
    width: 100px;
    height: 100px;
    position: absolute;
    background: green;
}

JavaScript

(function($) {
    $.fn.collidesWith = function(elements) {

        var checkEls = $(elements);
        var collideEls = $([]);

        if (!this || !checkEls) return;

        this.each(function() {
            var el = $(this);

            // define minimum and maximum coordinates
            var elOff = el.offset();
            var elMinX = elOff.left;
            var elMinY = elOff.top;
            var elMaxX = elMinX + el.outerWidth();
            var elMaxY = elMinY + el.outerHeight();

            checkEls.not(el).each(function() {
                var checkEl = $(this);
                var checkElOff = checkEl.offset();
                var checkElMinX = checkElOff.left;
                var checkElMinY = checkElOff.top;
                var checkElMaxX = checkElMinX + checkEl.outerWidth();
                var checkElMaxY = checkElMinY + checkEl.outerHeight();

                // check for intersection
                if (elMinX >= checkElMaxX || elMaxX <= checkElMinX || elMinY >= checkElMaxY || elMaxY <= checkElMinY) {
                    return true; // no intersection, continue each-loop
                } else {
                    // intersection found, add only once
                    if (collideEls.length == collideEls.not(this).length) {
                        collideEls.push(this);
                    }
                }
            });
        });
        // return collection
        return {
            elements: collideEls,
            collide: collideEls.length
        };
    };

    $.fn.move = function(dir, step, callback) {
        var el = this;

        switch (dir) {
        case "up":
            el.css({
                top: el.position().top - step
            });
            break;

        case "down":
            el.css({
                top: el.position().top + step
            });
            break;

        case "left":
            el.css({
                left: el.position().left - step
            });
            break;

    ...