<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
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |