Draggable Collision divek csoportos kijelölése esetén
2019-11-16T18:54:58+01:00
2019-11-17T02:12:36+01:00
2022-08-11T16:10:30+02:00
earlmanster
Üdv.

Igyekszek mindent leírni a problémámmal kapcsolatban, remélem sikerül. Leírom azt is, hogy mivel próbálkoztam, de max. csak részbeni sikerrrel.

Szóval: adott ez a plugin, amit használok:
JQuery UI Draggable Collision
(A plugin előfeltétele: https://sourceforge.net/projects/jquerycollision/)

Lebutítva így néz ki most a js fájlom:

// divek definíciói var d_OUTER = 'MAIN_DIV_outer'; var d_INNER = 'MAIN_DIV_inner'; // dragcollision var obstacle = 'placed'; var boundary = 'boundary'; // div multiselect definíciói var selected = $([]), offset = {top: 0, left: 0}; var multiSelectedDIV= $('.' + d_OUTER); var selectableArea = '#selectable'; $( function() { // próbálkozás a multicollisionra function WRAP() { console.log('.ui-selected'); /*$('.' + d_OUTER).filter('.ui-selected').wrapAll( "<div class='GROUP_CLASS' style='background-color: red; height: 0px; width: 0px; position: absolute;'>oké</div>" ); $('.' + d_OUTER).filter('.ui-selected').removeClass(obstacle); $('.' + d_OUTER).filter('.ui-selected').draggable('destroy'); $( '.GROUP_CLASS' ).each(function(index) { { var options = { collider: '.ui-selected', obstacle: '.' + obstacle, preventCollision: true, } } $( this ).draggable(options); });*/ } // ---------------------------------------------------------------------------------------------------------------------------------------------- // divek vonszolását beállító rész // ---------------------------------------------------------------------------------------------------------------------------------------------- $('.' + d_OUTER).each(function(index) { var options = { scroll : false, delay : 0, distance : 0, cursor : 'hand', snap : false, stack : '.' + d_OUTER, containment : 'body', opacity : opacity[0], // :: A JQuery Collision és a JQuery UI Draggable Collision pluginek működéséért felelős rész :: // // ====================================================================================================================================== obstacle : '.' + obstacle, preventCollision: true, preventProtrusion: true, //collider: '.ui-selected', //containment : 'body', //restraint: $(this), stop : function(e, ui) { var getattr = $(this).attr('id'); $(this).addClass(obstacle); $('.' + obstacle).removeClass(boundary).css({'opacity': opacity[2]}); $('.' + d_OUTER).not($(this)).find('.' + d_INNER).css( {'visibility' : 'visible'} ); }, // :: EDDIG :: // // ============== // // MULTISELECT 2/4 start: function(ev, ui) { if ($(this).hasClass('ui-selected')){ selected = $('.ui-selected').each(function() { var el = $(this); el.data('offset', el.offset()); el.removeClass(obstacle); // itt távolítom el az obstacle osztályt dragging előtt, de csoportosan nem vált ki hatást }); //WRAP(); } else { selected = $([]); $(multiSelectedDIV).removeClass('ui-selected'); } offset = $(this).offset(); }, // drag // ====================================================================================================================================== drag : function(ev, ui) { // MULTISELECT 3/4 var dt = ui.position.top - offset.top, dl = ui.position.left - offset.left; // take all the elements that are selected expect $("this"), which is the element being dragged and loop through each. selected.not(this).each(function() { // create the variable for we don't need to keep calling $("this") // el = current element we are on // off = what position was this element at when it was selected, before drag var el = $(this), off = el.data('offset'); el.css({top: off.top + dt, left: off.left + dl}); }); var thisPos = $(this).position(); var parentPos = $(this).parent().position(); window.cursor_pos_x = thisPos.left - parentPos.left; window.cursor_pos_y = thisPos.top - parentPos.top; window.getattr = $(this).attr('id'); /*if ($(this).hasClass('ui-selected')){ } else {*/ $(this).removeClass(obstacle); $('.' + obstacle).addClass(boundary).css({'opacity': opacity[1]}); $('.' + d_OUTER).not($(this)).find('.' + d_INNER).css( {'visibility' : 'hidden'} ); //} }, } $(this).draggable(options); }); });
A kód ezen része azt csinálja, hogy ha egy divet draggelek, akkor egy másik, azonos selectorú divre nem lehet ráhúzni, hanem azt kikerüli.
Lehetőség van multiselectre, vagyis olyan műveletre, amely pl. a Windows parancsikonjai esetén végezhető el, vagyis egérrel ki lehet jelölni a diveket, és azokat csoportosan draggelni lehet X pozícióból Y pozícióba.

A collision esetén van az obstacle változó, amely a draggelt/multidraggelt divek esetén eltávolításra kerül, és amely lehetővé teszi, hogy a többi, azonos selectorú div akadályt képezzen a draggeltek részére, hogy ne lehessen rájuk húzni.
Ez egy div esetén jól működik. Ha viszont többet jelölök ki, akkor hiába távolítom el az obstacle osztályt a draggeltekről, csak annál a divnél működik a collision, amelyiket az egérrel éppen vonszolom, a vele együtt tartó divnél ez nem működik. (el.removeClass(obstacle); sor)

A divek szerkezete így néz ki:
css:

.MAIN_DIV_outer { position: absolute; margin: 0px; padding: 1px; background-repeat: no-repeat; background-position: left 10px bottom 25px; outline: 0px dotted #aa22aa; font-size: 10px; font-weight: bold; text-align: center; } .MAIN_DIV_outer.placed.boundary { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4); -moz-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4); -webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4); transition: box-shadow 0.25s; background-color: transparent !important; min-height: 60px; background-repeat: repeat; } .MAIN_DIV_inner { width: 78px; line-height: 1.5; white-space:0; }
a PHP diveket kilistázó része:

function writeDisplayDivs() { echo '<div id="ID_' . $GLOBALS['id'] . '" class="MAIN_DIV_outer placed" style="left: ' . $GLOBALS['pos_x'] . '; top: ' . $GLOBALS['pos_y'] . ';"> <div class="MAIN_DIV_inner"> <!-- TARTALOM --> </div> </div>'; }
A JQuery UI Draggable Collision plugion oldalán a főoldalon van ez a plugin példakódjából kivett kép:
https://a.fsdn.com/con/app/proj/jquidragcollide/screenshots/jquidc3...

(a plugin letöltése esetén a jquery-ui-draggable-collision-multi-collision-interactions-example.html fájl)

Ez jó lenne multicollisionra, mert piros divek azok, amelyek egyszerre mozognak, a szürke divek azok, amelyek az akadályok, ezeket szépen kikerülik a mozgatott divek.
Nálam az volt a próbálkozás, hogy csináltam egy WRAP(); funkciót, ami a kijelölt divek köré egy abszolút pozíciójú divet készített, eltávolította az obstacle változót a kijelölt divekről, és a wrappelt divre dragginget készít a megjelölt opciókkal.
Ha ebben a funkcióban ledestroyolom a kijelölt divek dragjét, akkor működne az egész, azonban ez nem lenne elegáns megoldás, ráadásul szaggat a drag elég rendesen. Szerintem a legjobb megoldás lenne a drag startja esetén a loopban az obstacle osztályt eltávolítani a kijelölt divekről, de ez meg nem működik.

Csatoltam gifként a divek jelenlegi viselkedését.
Rubik kocka videók és leírások

Bármilyen tippet szívesen fogadok.
Mutasd a teljes hozzászólást!

  • Kis kiegészítés a kódhoz:
    A multiselect 4/4 kódrészlete a kód legalján van, kívül a $('.' + d_OUTER).each(function(index) {} ágon:

    // ---------------------------------------------------------------------------------------------------------------------------------------------- // MULTISELECT 4/4 // ---------------------------------------------------------------------------------------------------------------------------------------------- $( selectableArea ).selectable({ cancel: ".context-menu-list,.context-menu-item", });
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd