Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body style="margin-left: 50px; margin-right: 70px">
  <div id="coordinates" style="margin-bottom: 10px"></div>
  <div id="point" style="border: 1px solid red; position: absolute; padding: 5px; border-radius: 50%"></div>
  <div data-block-id="1" style="border: 1px solid red; padding: 10px;" >Rectangle 1</div>
  <div style="height: 50px"></div>
  <div data-block-id="2" style="border: 1px solid red; padding: 10px;">Rectangle 2</div>
  <div style="height: 166px"></div>
  <div data-block-id="2" style="border: 1px solid red; padding: 10px; margin: 30px">Rectangle 2</div>
</body>
  <script>
  function pDistance(x, y, x1, y1, x2, y2) {
    // Calculate the differences in x and y between the two endpoints of the line segment
    const dx = x2 - x1;
    const dy = y2 - y1;
    // Handle the special case of a zero-length line segment
    if (dx + dy === 0) {
      // Calculate and return the distance to the single point (x1, y1)
      return Math.hypot(x - x1, y - y1);
    }
    // Calculate the parameter 't' which represents the point's position along the line segment
    const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
    // Check if the point is outside the line segment on the side of 'x1'
    if (t < 0) {
      // Calculate and return the distance to the 'x1' endpoint
      return Math.hypot(x - x1, y - y1);
    } else if (t > 1) {
      // Check if the point is outside the line segment on the side of 'x2'
      // Calculate and return the distance to the 'x2' endpoint
      return Math.hypot(x - x2, y - y2);
    }
    // Calculate the coordinates of the projection point on the line segment
    const projectionX = x1 + t * dx; // X-coordinate of the projection
    const projectionY = y1 + t * dy; // Y-coordinate of the projection
    // Calculate and return the distance from the point to the projection point
    return Math.hypot(x - projectionX, y - projectionY);
  }
function findClosestRectangleEdge(x, y, rectangles) {
  let closestRectangle = null;
  let closestEdge = null;
  let closestDistance = Number.MAX_SAFE_INTEGER;
  for (const rectangle of rectangles) {
    const rect = rectangle.getBoundingClientRect();
    const edges = [
      { x1: rect.left, y1: rect.top, x2: rect.right, y2: rect.top, edge: "top" },
      { x1: rect.right, y1: rect.top, x2: rect.right, y2: rect.bottom, edge: "right" },
      { x1: rect.left, y1: rect.bottom, x2: rect.right, y2: rect.bottom, edge: "bottom" },
      { x1: rect.left, y1: rect.top, x2: rect.left, y2: rect.bottom, edge: "left" },
    ];
    for (const edge of edges) {
      const distance = pDistance(x, y, edge.x1, edge.y1, edge.x2, edge.y2);
      if (distance < closestDistance) {
        closestRectangle = rectangle;
        closestEdge = edge.edge;
        closestDistance = distance;
      }
    }
  }
  return { closestRectangle, closestEdge, closestDistance };
}
const onMouseMove = (event) => {
  const coordinatesEl = document.getElementById("coordinates");
  coordinatesEl.innerHTML = `${event.clientX}px, ${event.clientY}px`;
  const point = document.getElementById("point");
  point.style.left = `${event.clientX}px`;
  point.style.top = `${event.clientY}px`;
  const elements = document.querySelectorAll("[data-block-id]");
  elements.forEach((element) => (element.style.border = "1px solid red"));
  const { closestRectangle, closestEdge, closestDistance } =
    findClosestRectangleEdge(event.clientX, event.clientY, elements);
  if (closestEdge === "top") {
    closestRectangle.style.borderTop = "2px solid green";
  } else if (closestEdge === "bottom") {
    closestRectangle.style.borderBottom = "2px solid green";
  } else if (closestEdge === "left") {
    closestRectangle.style.borderLeft = "2px solid green";
  } else {
    closestRectangle.style.borderRight = "2px solid green";
  }
};
addEventListener("mousemove", onMouseMove);
  </script>
</html>
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers