使用CSS和JavaScript在两个元素之间划一条线

我试图在我的页面上的两个点之间划一条线。 这些图像可拖动并可放置到DIV中,因此它们的位置可以更改,但仍需要连接它们。

到目前为止,我只用一条自定义的线来尝试这一点。

var s = document.getElementById("Red1X");
var x = 200, y = 200;
s.style.x2 = x + "px";
s.style.y2 = y + "px";

function allowDrop(ev) {
    ev.preventDefault();
}
function drag(ev) {
    ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text");
    ev.target.appendChild(document.getElementById(data));
}
#div1 {
    width: 17px;
    height: 17px;
    padding: 0px;
    border: 1px solid #aaaaff;
    float: left
}
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

<img id="RED1" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">

<img id="RED2" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">

<svg height="500" width="500">
  <line id="Red1X" x1="0" y1="0" x2="100" y2="200" style="stroke:rgb(255,0,0);stroke-width:3" />
</svg>

好的,正如评论中提到的那样,点在同一行时相对容易。

事情变得更复杂,如果你有一个高于另一个 - 然后你基本上需要:角度,将其应用于CSS transform:旋转属性,以及两个点/元素之间的长度,重新计算宽度,因为它不再是直线。 我讨厌数学:),所以我使用来自互联网的好人的知识:http://jsfiddle.net/codepo8/bAwUf/light/(学分到codepo8

两条最重要的路线:

var angle= Math.atan2(red2.offsetTop - red1.offsetTop, red2.offsetLeft - red1.offsetLeft) * 180 / Math.PI;
var length = Math.sqrt((red2.offsetLeft-red1.offsetLeft) * (red2.offsetLeft-red1.offsetLeft) + (red2.offsetTop-red1.offsetTop) * (red2.offsetTop-red1.offsetTop));

而现在,你的脚本应该是这样的:

var s = document.querySelector(".line");
red1=document.getElementById('RED1');
red2=document.getElementById('RED2');

function allowDrop(ev) {
    ev.preventDefault();
}
function drag(ev) {
    ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text");
    ev.target.appendChild(document.getElementById(data));
 
    s.style.left=red1.offsetLeft+5+'px';
    s.style.top=red1.offsetTop+5+'px';
    
     s.style.visibility='visible';
var angle= Math.atan2(red2.offsetTop - red1.offsetTop, red2.offsetLeft - red1.offsetLeft) * 180 / Math.PI;
var length = Math.sqrt((red2.offsetLeft-red1.offsetLeft) * (red2.offsetLeft-red1.offsetLeft) + (red2.offsetTop-red1.offsetTop) * (red2.offsetTop-red1.offsetTop));
 s.style.width=Math.abs(length)+'px';

     
       s.style.transform="rotate("+Math.round(angle)+"deg)";
       s.style.transformOrigin ="0 0"; 
     
  
    
}
.div1 {
    width: 150px;
    height: 150px;
    padding: 0px;
    border: 1px solid #aaaaff;
    float: left;
   
}
.line {
  position:absolute;
  height:3px;
  background:red;
  width:100px;
  z-index:999;
  visibility:hidden;
}
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

<img id="RED1" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">

<img id="RED2" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">



<div class="line">

</div>

这里有一个使用jQuery和jQuery UI定位插件的例子。

  • 调整SVG,使其成为您的背景。 这样,它不会妨碍点击点。

    <svg style="position:absolute;top:0;left:0;height:100%;bottom:100%;z-index:-1">
      <line id="Red1X" x1="0" y1="0" x2="100" y2="200" style="stroke:rgb(255,0,0);stroke-width:3" />
    </svg>
    <div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
    <div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
    <div class="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
    <img id="RED1" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">
    <img id="RED2" src="http://i.imgur.com/By4xvE5.png" draggable="true" ondragstart="drag(event)" align="left">
    
  • 在放置时,您需要通过抓住点的位置并修改SVG的x1,y1,x2,y2坐标来重新定位线条。

    function positionLine(){
        d1.data('position', d1.position());
        d2.data('position', d2.position());
        line.attr('x1', d1.data('position').left + (d1.width() / 2));
        line.attr('y1', d1.data('position').top + (d1.height() / 2));
        line.attr('x2', d2.data('position').left + (d2.width() / 2));
        line.attr('y2', d2.data('position').top + (d2.height() / 2));
    }
    
  • 这是一个有效的Plunker:https://plnkr.co/edit/1fVBcqRsxc7r6gFZx0bR?p=preview


    你需要在这里做几件事。

  • 拖放时,获取拖动目标(红点)的(x,y)坐标:
  • function drop(ev) {
        ...
        var dataEl = document.getElementById(data);
        ev.target.appendChild(dataEl);
    
        // Get the dimensions (see https://developer.mozilla.org/en/docs/Web/API/Element/getBoundingClientRect)
        var rect = dataEl.getBoundingClientRect();
        var x = rect.x;
        var y = rect.y;
        ...
    }
    
  • SVG需要一些CSS:

  • position: fixedposition: absolute以便我们可以将它放置在其他元素的顶部。
  • z-index: 10 ,其中10是大于其他元素的z-索引的数字。 这将使该行显示在顶部而不是在框/圆圈下。
  • 继续drop功能,我们现在想要将SVG线的位置设置为圆圈的位置。 这里棘手的部分是,我们需要知道它是否连接到第一个圆。 为了达到这个目的,可以用类似isFirstConnectedEdge的形式来使用布尔值。 如果isFirstConnectedEdge === true ,那么你可以确保你设置了正确的x,y值。

    对于这个例子,我们使用'第一个连接的边将始终使用x1和y1值,第二个连接的边,以及所有更多的将设置x2和y2的启发式。 如果你想让箭头显示边缘的方向,这会让你陷入麻烦,但是现在我们将把它留下。 为了粗略地扩展前面步骤的代码,我们将在drop函数中执行如下操作:

  • if (isFirstConnectedEdge) {
        s.style.x1 = x;
        s.style.y1 = y;
    } else {
        s.style.x2 = x;
        s.style.y2 = y;
        isFirstConnectedEdge = false;
    }
    
  • 最后,你需要考虑很多事情。 该线将定位到该圆的元素的左上角。 您需要使用类似var x = rect.x + (rect.width / 2)的东西才能获得居中的行。
  • 链接地址: http://www.djcxy.com/p/37769.html

    上一篇: Make a Line between two elements using CSS and JavaScript

    下一篇: What are the options for storing hierarchical data in a relational database?