2011-06-08 4 views
76

Tak Wiem, że tego rodzaju pytania były zadawane wcześniej w następujących odsyłaczach: Question 1, Question 2 i Question 3. Ale moje pytanie różni się od już zadanych pytań.Rysowanie linii między dwoma przeciągalnymi elementami div

Co chcę, to następujące: Mam dwa duble ciągnione i mają łącznik (linia prosta) między nimi (narysowany linią SVG). Kiedy przesuwam te przeciągalne elementy div, muszę odpowiednio przesunąć złącze między nimi. Moje pytanie jest bardziej podobne do Question 3, ale w tym pytaniu, gdy użytkownik tworzy połączenie między divami, te divy przestają być przeciągane, więc nie dbają o odświeżające konektory.

Czy ktoś kiedykolwiek spotkał się z jakimkolwiek działającym przykładem lub demonstracją tego, co mówię? A może ktoś mógłby dać mi pomysły, jak to zrobić w optymalny sposób, proszę?

Na wszelki wypadek używam jQuery jako ramy javascript (jeśli warto o tym wiedzieć).

Wielkie dzięki.

UPDATE 1

Znalazłem to demo również, ale działa bardzo źle, powiedziałbym nieprawidłowo.

+0

otrzymuję alert antywirusowy z tego demo-link – Antti

Odpowiedz

146

Użyj jsPlumb - najlepszej biblioteki do rysowania niestandardowych linii na stronie.

https://jsplumbtoolkit.com/demos.html

+0

Bardzo mocny biblioteka myślę. Spróbuję odkryć i wykorzystać to. Myślę, że dokładnie tego szukałem. – Bakhtiyor

+7

Awesome ... Te "rzeczy, które ludzie robią" nie mają granic! – heltonbiker

+1

Ta biblioteka jest nierealna. Nie mogę uwierzyć, jak to działa. Łał! – crush

24

łączące linie z pomostów żylnych było warto spróbować dla mnie, i to działało idealnie ... Przede wszystkim, Scalable Vector Graphics (SVG) jest wektorem format obrazu, oparty na XML dla dwuwymiarowy grafika z obsługą interaktywności i animacji. Obrazy SVG i ich zachowania są zdefiniowane w plikach tekstowych XML. możesz utworzyć svg w HTML przy użyciu tagu <svg>. Adobe Illustrator jest jednym z najlepszych programów służących do tworzenia złożonych svg za pomocą ścieżek.

Procedura łączenia dwóch div przy użyciu wiersza:

  1. tworzyć dwa DIV i dać im żadnego stanowiska, jak trzeba

    <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> 
    

    (w trosce o wyjaśnienia robię jakiś inline stylizacji ale zawsze dobrze jest zrobić osobny plik CSS do stylizacji)

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

    Znacznik linii pozwala nam narysować linię między dwoma określonymi punktami (x1, y1) i (x2, y2). (w przypadku wizyty referencyjnej w3schools.) jeszcze ich nie sprecyzowaliśmy. ponieważ będziemy używać jQuery do edycji atrybutów (x1, y1, x2, y2) tagu linii.

  3. w <script> tag napisać

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

    użyłem selektorów, aby wybrać dwa div i linię ...

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

    jQuery position() metoda pozwala uzyskać aktualną pozycję elementu.Aby uzyskać więcej informacji, odwiedź https://api.jquery.com/position/ (można użyć offset() sposób zbyt)

Teraz jak możemy uzyskać wszystkie pozycje, których potrzebujemy, możemy wyciągnąć linię następująco ...

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

jQuery .attr() metody służy do zmiany atrybutów wybranego elementu.

Wszystko robiliśmy w powyższej linii jest zmieniliśmy atrybuty zgodne z

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

do

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

jak position() zwrotów dwie wartości, jeden „w lewo”, a drugi „top”, możemy łatwy dostęp do nich za pomocą .top i .left przy użyciu obiektów (tutaj poz1 i poz2) ...

Teraz znacznik linii ma dwa różne współrzędne, aby narysować linię między dwoma punktami.

Wskazówka: dodaj detektory zdarzeń jak trzeba DIV

Wskazówka: upewnij się, że import biblioteki jQuery pierwszy przed napisaniem czegokolwiek w tagu skrypt

Po dodawania współrzędnych poprzez JQuery ... to będzie wyglądać następująco

Poniższy urywek jest dla celów demonstracyjnych tylko, należy wykonać powyższe czynności, aby uzyskać poprawne rozwiązanie

<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>

+2

Prosimy nie kopiować i nie wklejać tej samej odpowiedzi do wielu pytań. Zamiast tego dostosuj odpowiedzi do poszczególnych pytań. – Andy

+2

Potrzebuję umieścić svg na szerokości i wysokości w 100% w tle używając z-index -1, ale działa jak urok. – steven

+2

Ta odpowiedź została skopiowana z http://stackoverflow.com/questions/19382872/how-to-connect-html-divs-with-lines –

2

ja też mam ten sam wymóg kilka dni wstecz

użyłem pełnej szerokość i wysokośćsvg i dodaje go poniżej wszystkich moich div i dodał linie do tych svg dynamicznie.

kasie jak zrobiłem to tutaj używając 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); 
});