poldeeek
poldeeek

Reputation: 333

Drawing a path between points in javascript/react/css

I am trying to draw a path between points wihtout using canvas or any other librares. Everything works fine for positive degrees, but it doesn't for negative..

My "points" are 150x150 [px], that's why there is that +75px in left position.

This is my code:

  useEffect(() => {
    let x1 = spider1.x;
    let y1 = spider1.y;
    let x2 = spider2.x;
    let y2 = spider2.y;

    if (x1 > x2) {
      let xTmp = x1;
      let yTmp = y1;
      x1 = x2;
      y1 = y2;
      x2 = xTmp;
      y2 = yTmp;
    }
    if (x1 === x2) {
      const height = Math.abs(y2 - y1).toString();
      setStyle({
        width: '5px',
        left: (x1 + 75).toString() + 'px',
        top: `${Math.min(y1, y2) + 75}px`,
        height: `${height}px`,
        transform: 'rotate(0deg)'
      });
    } else {
      const a = (y2 - y1) / (x2 - x1);
      const radians = Math.atan(a);
      const degrees = radians * (180 / Math.PI);

      setStyle({
        width: `${Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))}px`,
        left: (x1 + 75).toString() + 'px',
        top: `${Math.min(y1, y2) + 75}px`,
        height: `5px`,
        transform: `rotate(${degrees}deg)`,
        transformOrigin: `${degrees > 0 ? '0% 0%' : '100% 100%'}`
      });
    }
  }, [spider1, spider2]);

  return <div className='net' style={style} ref={myRef}></div>;

And the net class:

.net {
  position: absolute;
  background-color: red;
  z-index: 90;
}

On the screens we have the same objects, but the degrees on the second one are "-" and the line doesn't connect that two squares because of that

photo1 photo2

Upvotes: 1

Views: 1343

Answers (1)

John
John

Reputation: 3775

This example works. You will have to compare yours with mine as to what the differences are.

Note: I just wrote it from scratch rather using your example.

Just click "Random position"

var button = document.getElementById("new-points");

button.onclick = function() {

  var xy1 = {
       m_x : Math.floor((Math.random() * 200) + 1),
     m_y : Math.floor((Math.random() * 200) + 1),
   };
  
   var xy2 = {
      m_x : Math.floor((Math.random() * 200) + 1),
      m_y : Math.floor((Math.random() * 200) + 1),
   };
  
   var dotA =  document.getElementById("dotA");
   dotA.style.left = (xy1.m_x - 5) + "px";
   dotA.style.top = (xy1.m_y - 5) + "px";

   var dotB =  document.getElementById("dotB");
   dotB.style.left = (xy2.m_x - 5) + "px";
   dotB.style.top = (xy2.m_y - 5) + "px";

   var line = document.getElementById("line");
            
   var distance = Math.hypot(xy2.m_x - xy1.m_x, xy2.m_y - xy1.m_y);
            
   line.style.width = distance + "px";
   line.style.left = xy1.m_x + "px";
   line.style.top = xy1.m_y + "px";
            
   var angle = ((Math.atan2(xy1.m_x - xy2.m_x, xy2.m_y - xy1.m_y) + (Math.PI / 2.0)) * 180 / Math.PI);
   line.style.transform = "rotate(" + angle + "deg)";
   line.style.display = "block";
}
#new-points {
  border: 1px solid black;
  padding: 5px;
  width: 200px;
  text-align: center;
}

.dot {
   position: absolute;
   width: 10px;
   height: 10px;
   background: blue;
 }
 
 #line {
   position: absolute;
   border-top: solid 1px red;
   height: 1px;
   max-height: 1px;
   transform-origin: 0% 0%;
 }
<div id="dotA" class="dot"></div>

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


<div id="new-points" style="">
Random position
</div>

I've also tried the atan method for the above and it doesn't work. You can try it yourself and see what happens.

Upvotes: 1

Related Questions