Saltar al contenido

Detección de colisiones de jQuery / JavaScript

Ya no busques más por otras webs porque estás al sitio exacto, tenemos la respuesta que necesitas y sin complicarte.

Solución:

var overlaps = (function () 
    function getPositions( elem ) 
        var pos, width, height;
        pos = $( elem ).position();
        width = $( elem ).width();
        height = $( elem ).height();
        return [ [ pos.left, pos.left + width ], [ pos.top, pos.top + height ] ];
    

    function comparePositions( p1, p2 ) 

    return function ( a, b ) 
        var pos1 = getPositions( a ),
            pos2 = getPositions( b );
        return comparePositions( pos1[0], pos2[0] ) && comparePositions( pos1[1], pos2[1] );
    ;
)();

$(function () 
    var area = $( '#area' )[0],
        box = $( '#box0' )[0],
        html;
    
    html = $( area ).children().not( box ).map( function ( i ) 
        return '

Red box + Box ' + ( i + 1 ) + ' = ' + overlaps( box, this ) + '

'; ).get().join( '' ); $( 'body' ).append( html ); );
body 
    padding: 30px;
    color: #444;
    font-family: Arial, sans-serif;


h1 
    font-size: 24px;
    margin-bottom: 20px;


#area 
    border: 2px solid gray;
    width: 500px;
    height: 400px;
    position: relative;


#area > div 
    background-color: rgba(122, 122, 122, 0.3);
    position: absolute;
    text-align: center;
    font-size: 50px;
    width: 60px;
    height: 60px;


#box0 
    background-color: rgba(255, 0, 0, 0.5) !important;
    top: 150px;
    left: 150px;


#box1 
    top: 260px;
    left: 50px;


#box2 
    top: 110px;
    left: 160px;


#box3 
    top: 200px;
    left: 200px;


#box4 
    top: 50px;
    left: 400px;


p 
    margin: 5px 0;

Detect overlapping with JavaScript

1
2
3
4

Idea general: obtiene el desplazamiento y la dimensión de las cajas y comprueba si se superponen.

Si desea que se actualice, puede usar setInterval:

function detectOverlapping() 
    // code that detects if the box overlaps with a moving box
    setInterval(detectOverlapping, 25);


detectOverlapping();  

Además, tenga en cuenta que puede optimizar la función para su ejemplo específico.

  • no tiene que leer las dimensiones de la caja repetidamente (como yo hago en mi código) ya que son fijas. Puede leerlos al cargar la página (en una variable) y luego simplemente leer la variable

  • la posición horizontal de la pequeña caja no cambia (a menos que el usuario cambie el tamaño de la ventana). Las posiciones verticales de las cajas del coche no cambian. Por lo tanto, esos valores tampoco tienen que leerse repetidamente, sino que también se pueden almacenar en variables.

  • no tiene que probar si la pequeña caja se superpone con todas las cajas del automóvil en todo momento. Puede, en función de su posición vertical, averiguar en qué carril se encuentra actualmente la caja y probar solo la caja de automóvil específica de ese carril.

Creo que esta es la forma más fácil: https://plugins.jquery.com/overlaps/

Aquí hay otro, en alemán: http://www.48design.de/news/2009/11/20/kollisionsabfrage-per-jquery-plugin-update-v11-8/

Les daría una oportunidad.

–ACTUALIZAR–

Realmente no puedo gastar tiempo en eso en este momento, pero puedo cuando llegue a casa si nadie responde más que tú; haría algo como:

setInterval(function()
            //First step would be to get the offset of item 1 and item 2
            //Second would be to get the width of each
            //Third would be to check if the offset+width ever overlaps
                //the offset+width of the 2nd
            //Fourth would be, if so, do X or set a class...
        ,10);

Es un poco tarde en esto, pero supongo que podría usar este enfoque que probé cuando me enfrenté a una situación similar. La ventaja aquí es que no hay ningún complemento adicional o scripts involucrados y tampoco tiene que introducir un sondeo hambriento de rendimiento en él. Esta técnica utiliza los métodos y eventos integrados que ofrece el droppable de Jquery.

Ok, suficiente dicho, aquí está la técnica de solución: digamos que si tiene dos elementos (imágenes en mi caso) y no quiere que se superpongan o detecten cuando lo hacen, haga que los dos elementos se puedan soltar y haga que ‘acepten’ mutuamente:

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

El ‘CONFIG_COLLISSION_PREVENTION_DROPPABLE’ se ve así:

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);
     

Los controladores ‘activar’ y ‘soltar’ se refieren a los eventos ‘dropactivate’ y ‘soltar’ del complemento “soltar”

Aquí el key es la devolución de llamada ‘drop’. Siempre que cualquiera de los dos elementos se superponga y se coloquen uno sobre el otro, se llamará a la ‘gota’. Este es el lugar para detectar y tomar acciones, puede estar enviando eventos personalizados o llamando a otras acciones (aquí elegí revertir las posiciones del elemento superpuesto a la posición inicial cuando comenzó el arrastre, que se capturó en la devolución de llamada ‘activar’).

Eso es todo. Sin encuestas, sin complementos, solo los eventos integrados.

Bueno, se le pueden hacer otras optimizaciones / extensiones, esta fue simplemente la primera toma de mi cabeza que funcionó 🙂

También puede usar los eventos ‘dropover’ y ‘dropout’ para señalar y crear una retroalimentación visual para el usuario de que dos elementos se superponen, mientras que pueden estar todavía en movimiento.

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);
    
);

¡Espero que esto ayude!

Eres capaz de añadir valor a nuestro contenido participando con tu veteranía en las crónicas.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 4.5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *