14

Вопрос по jquery-ui-draggable, jquery – Направляющие при перемещении jquery-ui-перетаскиваемых блоков

Я работаю над тем, как показывать направляющие при перемещении полей, как это происходит в Google Docs Drawing. Я бы предпочел открытый код или руководство любого типа, прежде чем начать писать свой собственный.

  1. I do not need drag-n-drop across multiple browser windows so i don't need HTML5 Drag-n-Drop.
  2. Also i am using jquery-ui-draggable for boxes.

enter image description here

  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от Imran Naqvi
  • Error: User Rate Limit Exceededstackoverflow.com/a/39899249/3097810Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceededjsfiddle.net/kritzikratzi/x7uMh/1

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit ExceededWHENError: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • 10

    Я создал простой пример с линией границ рядом с перетаскиваемой рамкой

    . Он появляется, когда мы тащим на полеПосмотреть демо здесь

    HTML:

    <div id="canvas">
        <div id="box">
            <span class="topline"></span>
            <span class="rightline"></span>
            <span class="botline"></span>
            <span class="leftline"></span>
        </div>
    </div>
    

    CSS:

    #canvas {width: 1000px;height: 800px;}
    .topline{
        position:absolute;
        width: 1000%;
        border-top:1px red dotted;
        display:none;
        vertical-align::middle;
        margin-top:-7px;
        margin-left:-250%;
    }
    .botline{
        position:absolute;
        width: 1000%;
        bottom:-2px;
        border-bottom:1px red dotted;
        display:none;
        vertical-align::middle;
        margin-top:500px;
        margin-left:-250%;
    }
    .leftline{
        position:absolute;
        height: 1000%;
        left:-2px;
        border-left:1px red dotted;
        display:none;
        vertical-align::middle;
        margin-top:-250%;
    
    }
    .rightline{
        position:absolute;
        height: 1000%;
        right:-2px;
        border-right:1px red dotted;
        display:none;
        vertical-align::middle;
        margin-top:-250%;
    
    }
    #box {
        cursor: move;
        border:1px solid black;
        width:150px;
        height:100px;
        min-width:80px;
        min-height:80px;
        padding:5px;
        background-color:#1196c1;
    
    }
    

    JavaScript:

    $(function() {
        $("#box").draggable({
            containment: "#canvas",
            drag: function() {
                $(this).find($('.topline')).css('display', 'block');
                $(this).find($('.rightline')).css('display', 'block');
                $(this).find($('.botline')).css('display', 'block');
                $(this).find($('.leftline')).css('display', 'block');
            },
            start: function() {
                $(this).find($('.topline')).css('display', 'block');
                $(this).find($('.rightline')).css('display', 'block');
                $(this).find($('.botline')).css('display', 'block');
                $(this).find($('.leftline')).css('display', 'block');
            },
            stop: function() {
                $(this).find($('.topline')).css('display', 'none');
                $(this).find($('.rightline')).css('display', 'none');
                $(this).find($('.botline')).css('display', 'none');
                $(this).find($('.leftline')).css('display', 'none');
            }
        });
    });
    

  • 27

    Error: User Rate Limit Exceeded

    если вы настаиваете на рекомендациях, вам, возможно, придется раскошелиться на jqueryui или посмотреть на источник и посмотреть, сможете ли вы его расширить.

    в качестве альтернативы, вы можете просто добавить свои собственные функции привязки поверх jQuery ui, я немного поиграл с ним, и хотя это не кажется забавным, по крайней мере, это также не кажется очень сложным.

    Вы можете посмотреть пример на jsfiddle:http://jsfiddle.net/x7uMh/103/ update: this works ~ jQuery 1.9 + jQueryUI 1.9. it breaks in newest jquery+ui. не может быть обеспокоен, чтобы увидеть, в чем именно проблема, хотя, как правило, ее единственные незначительные проблемы. на тот случай, если этот сайт выйдет из строя, вот код:

    CSS

    body{
        font-family: courier new, courier; 
        font-size: 12px; 
    }
    
    .draggable{
        border: 1px solid #ccc; 
        display: inline-block; 
        cursor: move;
        position: absolute;         
    }
    
    .guide{
        display: none; 
        position: absolute; 
        left: 0; 
        top: 0; 
    }
    
    #guide-h{
        border-top: 1px dashed #55f; 
        width: 100%; 
    }
    
    #guide-v{
        border-left: 1px dashed #55f; 
        height: 100%; 
    }
    ​
    

    HTML

    <div class="draggable">drag me!</div>
    <div class="draggable">you can drag me too, if you like</div>
    <div class="draggable">hep hep</div>
    
    <div id="guide-h" class="guide"></div>
    <div id="guide-v" class="guide"></div>
    ​
    

    var MIN_DISTANCE = 10; // minimum distance to "snap" to a guide
    var guides = []; // no guides available ... 
    var innerOffsetX, innerOffsetY; // we'll use those during drag ... 
    
    $( ".draggable" ).draggable({
        start: function( event, ui ) {
            guides = $.map( $( ".draggable" ).not( this ), computeGuidesForElement );
            innerOffsetX = event.originalEvent.offsetX;
            innerOffsetY = event.originalEvent.offsetY;
        }, 
        drag: function( event, ui ){
            // iterate all guides, remember the closest h and v guides
            var guideV, guideH, distV = MIN_DISTANCE+1, distH = MIN_DISTANCE+1, offsetV, offsetH; 
            var chosenGuides = { top: { dist: MIN_DISTANCE+1 }, left: { dist: MIN_DISTANCE+1 } }; 
            var $t = $(this); 
            var pos = { top: event.originalEvent.pageY - innerOffsetY, left: event.originalEvent.pageX - innerOffsetX }; 
            var w = $t.outerWidth() - 1; 
            var h = $t.outerHeight() - 1; 
            var elemGuides = computeGuidesForElement( null, pos, w, h ); 
            $.each( guides, function( i, guide ){
                $.each( elemGuides, function( i, elemGuide ){
                    if( guide.type == elemGuide.type ){
                        var prop = guide.type == "h"? "top":"left"; 
                        var d = Math.abs( elemGuide[prop] - guide[prop] ); 
                        if( d < chosenGuides[prop].dist ){
                            chosenGuides[prop].dist = d; 
                            chosenGuides[prop].offset = elemGuide[prop] - pos[prop]; 
                            chosenGuides[prop].guide = guide; 
                        }
                    }
                } ); 
            } );
    
            if( chosenGuides.top.dist <= MIN_DISTANCE ){
                $( "#guide-h" ).css( "top", chosenGuides.top.guide.top ).show(); 
                ui.position.top = chosenGuides.top.guide.top - chosenGuides.top.offset;
            }
            else{
                $( "#guide-h" ).hide(); 
                ui.position.top = pos.top; 
            }
    
            if( chosenGuides.left.dist <= MIN_DISTANCE ){
                $( "#guide-v" ).css( "left", chosenGuides.left.guide.left ).show(); 
                ui.position.left = chosenGuides.left.guide.left - chosenGuides.left.offset; 
            }
            else{
                $( "#guide-v" ).hide(); 
                ui.position.left = pos.left; 
            }
        }, 
        stop: function( event, ui ){
            $( "#guide-v, #guide-h" ).hide(); 
        }
    });
    
    
    function computeGuidesForElement( elem, pos, w, h ){
        if( elem != null ){
            var $t = $(elem); 
            pos = $t.offset(); 
            w = $t.outerWidth() - 1; 
            h = $t.outerHeight() - 1; 
        }
    
        return [
            { type: "h", left: pos.left, top: pos.top }, 
            { type: "h", left: pos.left, top: pos.top + h }, 
            { type: "v", left: pos.left, top: pos.top }, 
            { type: "v", left: pos.left + w, top: pos.top },
            // you can add _any_ other guides here as well (e.g. a guide 10 pixels to the left of an element)
            { type: "h", left: pos.left, top: pos.top + h/2 },
            { type: "v", left: pos.left + w/2, top: pos.top } 
        ]; 
    }
    
    ​
    

    надеюсь, это поможет, лучше всего, Ханси.

  • 1

    Error: User Rate Limit Exceeded

    snap

    drag: function(event, ui) 
            { 
                //var snapped = $(this).data('ui-draggable').snapElements; //## for new version of jquery UI
                var snapped = $(this).data('draggable').snapElements;
                /* Pull out only the snap targets that are "snapping": */
                var snappedTo = $.map(snapped, function(element) {
                    //return element.snapping ? element.item : null;
                    return element.snapping ? element : null;
                });
                if((snappedTo[0].left + snappedTo[0].width) == $(this).offset().left)
                {
                    console.log('right of snapped item');
                    $('#guide-v').css({'left': $(this).offset().left}).show();
                }else
                if((snappedTo[0].left)  == $(this).offset().left)
                {
                    console.log('left  of snapped item');
                    $('#guide-v').css({'left': $(this).offset().left}).show();
                }else $('#guide-v').hide();
    
                if((snappedTo[0].top)  == $(this).offset().top)
                {
                    console.log('top  of snapped item');
                    $('#guide-h').css({'top': $(this).offset().top}).show();
                }else
                if((snappedTo[0].top + snappedTo[0].height)  == $(this).offset().top)
                {
                    console.log('bottom  of snapped item');
                    $('#guide-h').css({'top': $(this).offset().top}).show();
                }else $('#guide-h').hide();
              }
          });
    

  • 0

    Я получил ответ на этот вопрос:

    Error: User Rate Limit Exceeded

    Error: User Rate Limit ExceededError: User Rate Limit Exceeded

    Error: User Rate Limit Exceeded

    <div id="parent">
        <div class="object1 dropped" style="left:0px;top:300px;background:#a00;"></div>
        <div class="object2 dropped"></div>
        <div class="object3 dropped" style="left:400px;top:20px;"></div>
        <div class="objectx"></div>
        <div class="objecty"></div>
    </div>
    

    Error: User Rate Limit Exceeded

    #parent{
        width:600px;
        height:500px;
        border:1px solid #000;
        position:relative;
    }
    .object1{
        background:#aaa;
        width:100px;
        height:100px;
        display:block;
        position:absolute;
        left:140px;
        top:50px;
    }
    .object2{
        background:#aaa;
        width:100px;
        height:150px;
        display:block;
        position:absolute;
        left:140px;
        top:50px;
    }
    .object3{
        background:#aaa;
        width:150px;
        height:100px;
        display:block;
        position:absolute;
        left:140px;
        top:50px;
    }
    .objectx{
        display:none;
        //background:#fff;
        width:0px;
        height:100%;
        position:absolute;
        top:0px;
        left:10px;
        border-left: 1px solid yellow;
    }
    .objecty{
        display:none;
        //background:#fff;
        width:100%;
        height:0px;
        position:absolute;
        top:10px;
        left:0px;
        border-bottom: 1px solid yellow;
    }
    

    JS:

    $.ui.plugin.add("draggable", "smartguides", {
        start: function(event, ui) {
            var i = $(this).data("draggable"), o = i.options;
            i.elements = [];
            $(o.smartguides.constructor != String ? ( o.smartguides.items || ':data(draggable)' ) : o.smartguides).each(function() {
                var $t = $(this); var $o = $t.offset();
                if(this != i.element[0]) i.elements.push({
                    item: this,
                    width: $t.outerWidth(), height: $t.outerHeight(),
                    top: $o.top, left: $o.left
                });
            });
        },
        stop: function(event, ui) {
            $(".objectx").css({"display":"none"});
            $(".objecty").css({"display":"none"});
        },
        drag: function(event, ui) {
            var inst = $(this).data("draggable"), o = inst.options;
            var d = o.tolerance;
            $(".objectx").css({"display":"none"});
            $(".objecty").css({"display":"none"});
                var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
                    y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height,
                    xc = (x1 + x2) / 2, yc = (y1 + y2) / 2;
                for (var i = inst.elements.length - 1; i >= 0; i--){
                    var l = inst.elements[i].left, r = l + inst.elements[i].width,
                        t = inst.elements[i].top, b = t + inst.elements[i].height,
                        hc = (l + r) / 2, vc = (t + b) / 2;
                         var lss = Math.abs(l - x1) <= d;
                                var ls = Math.abs(l - x2) <= d;
                                var rss = Math.abs(r - x2) <= d;
                                var rs = Math.abs(r - x1) <= d;
                                var tss = Math.abs(t - y1) <= d;
                                var ts = Math.abs(t - y2) <= d;
                                var bss = Math.abs(b - y2) <= d;
                                var bs = Math.abs(b - y1) <= d;
                                var hs = Math.abs(hc - xc) <= d;
                                var vs = Math.abs(vc - yc) <= d; 
                            if(lss) {
                                ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
                                $(".objectx").css({"left":ui.position.left,"display":"block"});
                            }
                            if(rss) {
                                ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
                                $(".objectx").css({"left":ui.position.left + ui.helper.width(),"display":"block"});
                            }
                            if(ls) {
                                ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
                                $(".objectx").css({"left":ui.position.left + ui.helper.width(),"display":"block"});
                            }
                            if(rs) {
                                ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
                                $(".objectx").css({"left":ui.position.left,"display":"block"});
                            }
                            if(tss) {
                                ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
                                $(".objecty").css({"top":ui.position.top,"display":"block"});
                            }
                            if(ts) {
                                ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
                                $(".objecty").css({"top":ui.position.top + ui.helper.height(),"display":"block"});
                            }
                            if(bss) {
                                ui.position.top = inst._convertPositionTo("relative", { top: b-inst.helperProportions.height, left: 0 }).top - inst.margins.top;
                                $(".objecty").css({"top":ui.position.top + ui.helper.height(),"display":"block"});
                            }
                            if(bs) {
                                ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
                                $(".objecty").css({"top":ui.position.top,"display":"block"});
                            }
                            if(hs) {
                                ui.position.left = inst._convertPositionTo("relative", { top: 0, left: hc - inst.helperProportions.width/2 }).left - inst.margins.left;
                                $(".objectx").css({"left":ui.position.left + (ui.helper.width()/2),"display":"block"});
                            }
                            if(vs) {
                                ui.position.top = inst._convertPositionTo("relative", { top: vc - inst.helperProportions.height/2, left: 0 }).top - inst.margins.top;
                                $(".objecty").css({"top":ui.position.top + (ui.helper.height()/2),"display":"block"});
                            }
    
    
                };
            }
    });
    $('.dropped').draggable({
        containment: 'parent',
        smartguides:".dropped",
        tolerance:5
    });