css, jquery настроить линию между перетаскиваемыми div - PullRequest
0 голосов
/ 17 января 2020

Я нарисовал линию, которая соединяет перетаскиваемые элементы div. Но, по мере перетаскивания div, линия теряет свою исходную и конечную точку (т.е. от одного div к другому div). Моя цель состоит в том, чтобы установить линию таким образом, чтобы она не теряла свой край от любого div, и, когда бы я ни перетаскивал div, он постоянно обновляет себя, то есть высоту, поворот, положение.

Извините за плохой английский sh. Пожалуйста помоги.....! Вот мой код

var coordinates = function(element) {
  element = $(element);
  var top = element.position().top;
  var left = element.position().left;

  //--------------line------------------------------
  var length = Math.sqrt(((left) * (left)) + ((top) * (top)));
  var angle = Math.atan2(top, left) * 180 / Math.PI;
  var transform = 'rotate(' + angle + 'deg)';

  $('#results').text('X: ' + left + ' ' + 'Y: ' + top).attr('style', 'margin-left:' + left + 'px');
  //$('#line1').attr('style', "margin-left:"+left+"px;margin-top:"+top+"px;height:"+(parseInt(100+top))+"px;transform:"+transform+";width:"+length+"px;");

  $('#line1').attr('style', "transform:" + transform + ";height:" + length + "px;");

}

//alert($('#box1').position().top);

$('#box1').draggable({
  start: function() {
    coordinates('#box1');
  },
  stop: function() {
    coordinates('#box1');
  }
});

$('#box2').draggable({
  start: function() {
    coordinates('#box2');
  },
  stop: function() {
    coordinates('#box2');
  }
});
.box {
  border: 1px solid black;
  background-color: #ccc;
  width: 100px;
  height: 100px;
  position: absolute;
}

.line {
  width: 1px;
  height: 100px;
  background-color: black;
  position: absolute;
}

#box1 {
  top: 0;
  left: 0;
}

#box2 {
  top: 200px;
  left: 0;
}

#box3 {
  top: 250px;
  left: 200px;
}

#line1 {
  top: 100px;
  left: 50px;
  /*transform: rotate(222deg);
    -webkit-transform: rotate(222deg);
    -ms-transform: rotate(222deg);*/
}

#line2 {
  top: 220px;
  left: 150px;
  height: 115px;
  transform: rotate(120deg);
  -webkit-transform: rotate(120deg);
  -ms-transform: rotate(120deg);
}
<div class="box" id="box1"></div>
<div class="box" id="box2"></div>


<div class="line" id="line1"></div>


<div id="results">test</div>

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

1 Ответ

3 голосов
/ 17 января 2020

Если вы сделаете вашу линию элементом svg, то вы можете манипулировать атрибутами x1, x2, y1 и y2 линии, основываясь на двух позициях блоков.

См. Пример ниже:

const $b1 = $("#box1");
const $b2 = $("#box2");
const $line = $("line");
const padding = 7;
const coordinates = function() {
  const x1 = $b1.offset().left + $b1.width()/2-padding;
  const y1 = $b1.offset().top + $b1.height()/2-padding;
  const x2 = $b2.offset().left + $b1.width()/2-padding;
  const y2 = $b2.offset().top + $b1.height()/2-padding;

  $line.attr("x1", x1);
  $line.attr("y1", y1);
  $line.attr("x2", x2);
  $line.attr("y2", y2);
}
coordinates();


$('#box1').draggable({
  drag: coordinates
});

$('#box2').draggable({
  drag: coordinates
});
.box {
  border: 1px solid black;
  background-color: #ccc;
  width: 100px;
  height: 100px;
  position: absolute;
}


#box1 {
  top: 0;
  left: 0;
}

#box2 {
  top: 200px;
  left: 0;
}
<div class="box" id="box1"></div>
<div class="box" id="box2"></div>

<svg height="1000" width="1000">
  <line id="line" x1="0" y1="0" x2="200" y2="200" style="stroke: rgb(0,0,0); stroke-width:1" />
</svg>


<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

Если вы хотите использовать div вместо svg, тот же результат может быть достигнут с помощью предоставленного вами createLine() метода:

const $b1 = $("#box1");
const $b2 = $("#box2");
const $line = $("#line");

const coordinates = function() {
  const x1 = $b1.offset().left + $b1.width()/2;
  const y1 = $b1.offset().top + $b1.height()/2;
  const x2 = $b2.offset().left + $b1.width()/2;
  const y2 = $b2.offset().top + $b1.height()/2;

  moveLine(x1, y1, x2, y2);  
}

coordinates();

function moveLine(x1, y1, x2, y2) {
    var length = Math.sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
    var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
    var transform = 'rotate(' + angle + 'deg)';

    offsetX = (x1 > x2) ? x2 : x1;
    offsetY = (y1 > y2) ? y2 : y1;
    
    $line.css({
        'position': 'absolute',
        '-webkit-transform': transform,
        '-moz-transform': transform,
        'transform': transform
      })
      .width(length)
      .offset({
        left: offsetX,
        top: offsetY
      });
}

$('#box1').draggable({
  drag: coordinates
});

$('#box2').draggable({
  drag: coordinates
});
.box {
  border: 1px solid black;
  background-color: #ccc;
  width: 100px;
  height: 100px;
  position: absolute;
}

#line1 {
  top: 100px;
  left: 50px;
  /*transform: rotate(222deg);
    -webkit-transform: rotate(222deg);
    -ms-transform: rotate(222deg);*/
}

.line {
  width: 1px;
  height: 1px;
  background-color: black;
  position: absolute;
  z-index: -1; /* put line behind the boxes */
}


#box1 {
  top: 0;
  left: 0;
}

#box2 {
  top: 200px;
  left: 0;
}
<div class="box" id="box1"></div>
<div class="box" id="box2"></div>

<div class="line" id="line"></div>
   

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

Для трех ящиков я предлагаю добавить атрибут data-connect, который указывает, к каким ячейкам подключается ваша линия. Затем вы можете l oop через каждую линию и нарисовать линии, соединяющие каждую коробку:

const coordinates = function() {

  $(".line").each(function() {
    const [box1, box2] = $(this).data("connect").split(',');
    const $b1 = $(box1);
    const $b2 = $(box2);
    
    const x1 = $b1.offset().left + $b1.width()/2;
    const y1 = $b1.offset().top + $b1.height()/2;
  
    const x2 = $b2.offset().left + $b2.width()/2;
    const y2 = $b2.offset().top + $b2.height()/2;

    moveLine(x1, y1, x2, y2, $(this)); 
  });

   
}

coordinates();

function moveLine(x1, y1, x2, y2, $line) {
    var length = Math.sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
    var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
    var transform = 'rotate(' + angle + 'deg)';

    var offsetX = (x1 > x2) ? x2 : x1;
    var offsetY = (y1 > y2) ? y2 : y1;
    
    $line.css({
        'position': 'absolute',
        '-webkit-transform': transform,
        '-moz-transform': transform,
        'transform': transform
      })
      .width(length)
      .offset({
        left: offsetX,
        top: offsetY
      });
}

$('.box').draggable({
  drag: coordinates
});
.box {
  border: 1px solid black;
  background-color: #ccc;
  width: 100px;
  height: 100px;
  position: absolute;
}

#line1 {
  top: 100px;
  left: 50px;
  /*transform: rotate(222deg);
    -webkit-transform: rotate(222deg);
    -ms-transform: rotate(222deg);*/
}

.line {
  width: 1px;
  height: 1px;
  background-color: black;
  position: absolute;
  z-index: -1; /* put line behind the boxes */
}


#box1 {
  top: 0;
  left: 0;
}

#box2 {
  top: 200px;
  left: 0;
}

#box3 {
  top: 200px;
  left: 200px;
}
<div class="box" id="box1"></div>
<div class="box" id="box2"></div>
<div class="box" id="box3"></div>

<div class="line" id="line" data-connect="#box1,#box2"></div>
<div class="line" id="line2" data-connect="#box1,#box3"></div>
   

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...