6

I'm trying to connect two points with a line while moving one of them. I'm really lost in finding the real x, y position of anything on a document... I've read about how paddings, element sizes and all these things can mess up this process, but none of the tutorials or example codes worked. I would really appreciate if you could give my code a look and give a solution/url to some kind of tutorial or just a basic startingpoint. Thanks in advance!

var node = document.querySelector("#node");
var startNode = document.querySelector("#startnode");
var container = document.querySelector("#container");

container.addEventListener("click", SetNodePosition, false);

function SetNodePosition(e) {

  startX = getPosition(startNode).x;
  startY = getPosition(startNode).y;

  nodeX = getPosition(node).x;
  nodeY = getPosition(node).y;

  console.log("StartNode: " + startX + " - " + startY);
  console.log("Node: " + nodeX + " - " + nodeY)

  var translate3dValue = "translate3d(" + nodeX + "px," + nodeY + "px, 0)";
  node.style.transform = translate3dValue;

  if(typeof(document.getElementById("line1")) != 'undefined' && document.getElementById("line1") != null){
      updateLine(startX, nodeX, startY, nodeY, "line1");
  }
  else{
      createLine(startX, nodeX, startY, nodeY, "line1");
  }
}

function getPosition(element) {

  //FIND AND RETURN ELEMENT X, Y POSITION
  
}

function createLine(x1, x2, y1, y2, lineId) {
    distance = Math.sqrt(((x1-x2)*(x1-x2)) + ((y1-y2)*(y1-y2)));

    xMid = (x1+x2)/2;
    yMid = (y1+y2)/2;

    slopeInRadian = Math.atan2(y1-y2, x1-x2);
    slopeInDegrees = (slopeInRadian*180)/Math.PI;

    var line = document.createElement("div");
    line.setAttribute("id", lineId);
    line.style.height = "2px"
    line.style.backgroundColor = "black"
    line.style.width = distance + "px";
    line.style.top = yMid + "px";
    line.style.left = (xMid - (distance/2)) + "px";
    line.style.transform = "rotate(" + slopeInDegrees + "deg)";
    document.getElementById("container").appendChild(line);

    console.log()
}

function updateLine(x1, x2, y1, y2, lineId) {
    distance = Math.sqrt(((x1-x2)*(x1-x2)) + ((y1-y2)*(y1-y2)));

    xMid = (x1+x2)/2;
    yMid = (y1+y2)/2;

    slopeInRadian = Math.atan2(y1-y2, x1-x2);
    slopeInDegrees = (slopeInRadian*180)/Math.PI;

    var line = document.getElementById(lineId)
    line.style.width = distance + "px";
    line.style.top = yMid + "px";
    line.style.left = (xMid - (distance/2)) + "px";
    line.style.transform = "rotate(" + slopeInDegrees + "deg)";
}
#container {
    background-color: cornflowerblue;
    height: 500px;
    width: 500px;
}
#startnode {
    height: 50px;
    width: 50px;
    background-color: green;
    border-radius: 50%;

    transform: translate3d(200px, 25px, 0);
}
#node {
    height: 50px;
    width: 50px;
    cursor: move;
    background-color: red;
    border-radius: 50%;

    transform: translate3d(50px, 50px, 0);
}

body {
    padding: 0;
    margin: 0;
}
<body>
    
    <div id="container">

        <div id="startnode"></div>
        <div id="node"></div>
      
    </div>
    
    <script src="./js/index.js"></script>
</body>

3
  • check this developer.mozilla.org/en-US/docs/Web/API/Element/… Commented May 12, 2020 at 12:14
  • getBoundingClientRect() will give the position of the element, all four corners of it Commented May 12, 2020 at 12:28
  • jQuery offset(); Commented May 12, 2020 at 12:30

2 Answers 2

4

getBoundingClientRect function will give you the x and y position of the element

function getPosition(element) {
  const rect = element.getBoundingClientRect();
  return { x: rect.left, y: rect.top };
}

In SetNodePosition function, instead of calling this function two times for each html element, call it once for each element as shown below

function SetNodePosition(e) {

  let { x: startNodeX, y:startNodeY } = getPosition(startNode);
  startX = startNodeX;
  startY = startNodeY;

  console.log("StartNode: " + startX + " - " + startY);

  ....
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much, it works great! Although I realised, this only solves half of my problems... I asked the wrong question basically. I'll make another post I guess, but just in case: the problem would be with finding the mouse location, as if I'm right, you can't use getBoundingClientRect() for a mouse location. Knowing the mouse pos would be neccesary for moving one of the points.
You can attach any mouse event on a container. To find the x and y position of mouse pointer when that event fires, use event.offsetX and event.offsetY respectively.
1

So, like you asked; with a canvas you can perform a lot of functions and a variety of libraries are available which can extend the functionality. So if you want to get the position of the box when you click on it, you can get that value.

Basically what I am doing is getting the mouse position all the time via canvas function and when you click, that position is written to a div

function writeMessage(canvas, message) {
        var context = canvas.getContext('2d');
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.font = '18pt Calibri';
        context.fillStyle = 'black';
        context.fillText(message, 10, 25);
      }
      
function mousePosition(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        return {
          x: evt.clientX - rect.left,
          y: evt.clientY - rect.top
        };
      }
      
      var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');

      canvas.addEventListener('mousemove', function(evt) {
        var mousePos = mousePosition(canvas, evt);
        var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
        writeMessage(canvas, message);
      }, false);
      
      canvas.addEventListener('click', function(evt) {
        var mousePos = mousePosition(canvas, evt);
        var message = 'Position: ' + mousePos.x + ',' + mousePos.y;
        document.getElementById('click').innerHTML = message;
      }, false);
<div style="background-color: #AAAAAA;" id="click">Not Clicked Yet
</div>
<canvas id="myCanvas" width="400" height="200"></canvas>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.