Guias ao mover checkboxs com jquery-ui-draggable

Estou trabalhando para mostrar guias ao mover checkboxs como no Google Docs Drawing. Eu preferiria um código de código aberto ou qualquer tipo de guia antes de começar a escrever o meu.

  1. Não preciso de arrastar e soltar em várias janelas do navegador para não precisar de arrastar e soltar HTML5.
  2. Também estou usando jquery-ui-draggable para checkboxs.

insira a descrição da imagem aqui

jquery ui já esta embutido, veja este demo: http://jqueryui.com/demos/draggable/#snap-to

Se você insistir nas diretrizes, talvez precise extrair o jqueryui ou ver a fonte e ver se consegue estendê-la.


Como alternativa, você poderia simplesmente adicionar suas próprias funções de encaixe em cima do jQuery ui, eu joguei com ele um pouco, e embora não pareça ser divertido, pelo menos, também não parece ser muito difícil.

você pode ver o exemplo em jsfiddle: http://jsfiddle.net/x7uMh/103/ update: isso funciona ~ jQuery 1.9 + jQueryUI 1.9. quebra no mais novo jquery + ui. Não poderia ser incomodado para ver o que exatamente é o problema, normalmente seus únicos problemas menores embora. apenas no caso de o site cair, aqui está o código:

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

 
drag me!
you can drag me too, if you like
hep hep

javascript (não se esqueça de include jquery + jquery ui)

 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 (eg 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 } ]; }​ 

Espero que ajude, melhor, hansi.

Eu criei um exemplo simples com apenas linhas de borda ao lado da checkbox arrastável. Ele aparece quando arrastamos a checkbox. Veja a demonstração aqui

HTML:

 

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

para aqueles que ainda tentam encontrar uma maneira de fazer isso, eu crio um violino

Eu usei snap e $ (this) .data (‘arrastável’). snapElements;

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

http://jsfiddle.net/j6zqN/1/

Eu tenho uma resposta a partir desta pergunta: JavaScript arrastar / soltar – estilo do Illustrator ‘guias inteligentes’

Eu acho que é isso que está procurando. Eu também o aprimorei apoiando a linha para o mesmo lado. Aqui está o JsFiddle: http://jsfiddle.net/yusrilmaulidanraji/A6CpP/120/

HTML

 

CSS:

 #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 }); 
Intereting Posts