Saya juga memiliki persyaratan yang sama beberapa hari yang lalu
Saya menggunakan lebar penuh dan tinggi svg dan menambahkannya di bawah semua div saya dan menambahkan baris ke svg ini secara dinamis.
Lihat bagaimana saya melakukannya di sini menggunakan 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);
});