在两个可拖动的div之间画一条线

是的,我知道在以下链接中已经询问过这类问题: 问题1 , 问题2和问题3 。 但是我的问题与已经提出的问题是完全不同的。

我想要的是:我有两个可拖动的div,并有一个连接器(一条直线)之间(用SVG线绘制)。 当我移动这些可拖动div的时候,我需要在它们之间移动一个连接器。 我的问题更类似于问题3 ,但是在那个问题中,一旦用户在div之间build立连接,那些div停止拖动,所以他们不关心刷新连接器。

有没有人遇到过我正在说的任何工作示例或演示? 或者,有没有人可以给我任何想法如何以最佳的方式做到这一点?

以防万一,我使用jQuery作为一个JavaScript框架(如果值得知道的话)。

非常感谢。

更新1

我也发现这个演示 ,但它工作非常糟糕,我会说错误的。

使用jsPlumb – 在网页上绘制自定义线条的最佳库。

https://jsplumbtoolkit.com/demos.html

与svgs结合的线条对我来说是值得的,它的工作非常完美…首先,可缩放vectorgraphics(SVG)是一种基于XML的vector图像格式,用于支持交互性和animation的二维graphics。 SVG图像及其行为在XML文本文件中定义。 你可以用<svg>标签在HTML中创build一个svg。 Adobe Illustrator是使用path创build复杂svgs的最佳软件之一。

使用一行连接两个div的过程:

  1. 创build两个div,并根据需要给他们任何位置

     <div id="div1" style="width: 100px; height: 100px; top:0; left:0; background:#e53935 ; position:absolute;"></div> <div id="div2" style="width: 100px; height: 100px; top:0; left:300px; background:#4527a0 ; position:absolute;"></div> 

    (为了解释我做了一些内联样式,但是为样式创build一个单独的css文件总是很好的)

  2. <svg><line id="line1"/></svg>

    线条标记允许我们在两个指定点(x1,y1)和(x2,y2)之间画一条线。 (参考访问w3schools。)我们还没有指定他们。 因为我们将使用jQuery来编辑行标记的属性(x1,y1,x2,y2)。

  3. <script>标签写入

     line1 = $('#line1'); div1 = $('#div1'); div2 = $('#div2'); 

    我用select器来select两个div和线…

     var pos1 = div1.position(); var pos2 = div1.position(); 

    jQuery的position()方法允许我们获取元素的当前位置。 有关更多信息,请访问https://api.jquery.com/position/ (也可以使用offset()方法)

现在,我们已经获得了我们需要的所有职位,我们可以按照以下方式划分线

 line1.attr('x1',pos1.left).attr('y1',pos1.top).attr('x2',pos2.left).attr('y2',pos2.top); 

jQuery .attr()方法用于更改所选元素的属性。

我们上面所做的是我们改变了线的属性

 x1=0 y1=0 x2=0 y2=0 

 x1 = pos1.left y1 = pos1.top x2 = pos2.left y2 = pos2.top 

作为position()返回两个值,一个'左'和其他'顶部',我们可以很容易地访问它们使用.top和.left使用对象(这里pos1和pos2)…

现在线标记有两个不同的坐标来绘制两点之间的线。

提示:添加事件侦听器,因为你需要div

提示:确保您先在脚本标记中写入任何内容之前先导入jQuery库

通过JQuery添加坐标 …看起来像这样

下面的代码只是为了演示目的,请按照上面的步骤来获得正确的解决scheme

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="div1" style="width: 100px; height: 100px; top:0; left:0; background:#e53935 ; position:absolute;"></div> <div id="div2" style="width: 100px; height: 100px; top:0; left:300px; background:#4527a0 ; position:absolute;"></div> <svg width="500" height="500"><line x1="50" y1="50" x2="350" y2="50" stroke="red"/></svg> 

几天前我也有同样的要求

我使用了一个完整的宽度高度的 SVG ,并将其添加到所有我的div下面,并dynamic地添加到这些svg的

检查我在这里使用svg

HTML

 <div id="ui-browser"><div class="anchor"></div> <div id="control-library" class="library"> <div class="name-title">Control Library</div> <ul> <li>Control A</li> <li>Control B</li> <li>Control C</li> <li>Control D</li> </ul> </div><!-- --></div><!-- --><div id="canvas"> <svg id='connector_canvas'></svg> <div class="ui-item item-1"><div class="con_anchor"></div></div> <div class="ui-item item-2"><div class="con_anchor"></div></div> <div class="ui-item item-3"><div class="con_anchor"></div></div> <div class="ui-item item-1"><div class="con_anchor"></div></div> <div class="ui-item item-2"><div class="con_anchor"></div></div> <div class="ui-item item-3"><div class="con_anchor"></div></div> </div><!-- --><div id="property-browser"></div> 

https://jsfiddle.net/kgfamo4b/

  $('.anchor').on('click',function(){ var width = parseInt($(this).parent().css('width')); if(width==10){ $(this).parent().css('width','20%'); $('#canvas').css('width','60%'); }else{ $(this).parent().css('width','10px'); $('#canvas').css('width','calc( 80% - 10px)'); } }); $('.ui-item').draggable({ drag: function( event, ui ) { var lines = $(this).data('lines'); var con_item =$(this).data('connected-item'); var con_lines = $(this).data('connected-lines'); if(lines) { lines.forEach(function(line,id){ $(line).attr('x1',$(this).position().left).attr('y1',$(this).position().top+1); }.bind(this)); } if(con_lines){ con_lines.forEach(function(con_line,id){ $(con_line).attr('x2',$(this).position().left) .attr('y2',$(this).position().top+(parseInt($(this).css('height'))/2)+(id*5)); }.bind(this)); } } }); $('.ui-item').droppable({ accept: '.con_anchor', drop: function(event,ui){ var item = ui.draggable.closest('.ui-item'); $(this).data('connected-item',item); ui.draggable.css({top:-2,left:-2}); item.data('lines').push(item.data('line')); if($(this).data('connected-lines')){ $(this).data('connected-lines').push(item.data('line')); var y2_ = parseInt(item.data('line').attr('y2')); item.data('line').attr('y2',y2_+$(this).data('connected-lines').length*5); }else $(this).data('connected-lines',[item.data('line')]); item.data('line',null); console.log('dropped'); } }); $('.con_anchor').draggable({drag: function( event, ui ) { var _end = $(event.target).parent().position(); var end = $(event.target).position(); if(_end&&end) $(event.target).parent().data('line') .attr('x2',end.left+_end.left+5).attr('y2',end.top+_end.top+2); },stop: function(event,ui) { if(!ui.helper.closest('.ui-item').data('line')) return; ui.helper.css({top:-2,left:-2}); ui.helper.closest('.ui-item').data('line').remove(); ui.helper.closest('.ui-item').data('line',null); console.log('stopped'); } }); $('.con_anchor').on('mousedown',function(e){ var cur_ui_item = $(this).closest('.ui-item'); var connector = $('#connector_canvas'); var cur_con; if(!$(cur_ui_item).data('lines')) $(cur_ui_item).data('lines',[]); if(!$(cur_ui_item).data('line')){ cur_con = $(document.createElementNS('http://www.w3.org/2000/svg','line')); cur_ui_item.data('line',cur_con); } else cur_con = cur_ui_item.data('line'); connector.append(cur_con); var start = cur_ui_item.position(); cur_con.attr('x1',start.left).attr('y1',start.top+1); cur_con.attr('x2',start.left+1).attr('y2',start.top+1); });