<svg>
<path></path>
</svg>
<h2>hold and drag corners</h2>
body {
display: grid;
grid-template-columns: 1fr 1fr;
}
svg {
outline: 1px dashed gray;
width: 250px;
height: 250px;
fill: #00968833;
stroke: #009688;
}
const svg = document.querySelector('svg');
const path = document.querySelector('path');
const dragRadius = 10;
const sides = {
top: 10,
right: 240,
bottom: 240,
left: 10
};
const corners = [
{ x: sides.left, y: sides.top },
{ x: sides.right, y: sides.top },
{ x: sides.right, y: sides.bottom },
{ x: sides.left, y: sides.bottom }
];
function render() {
let d = `M${corners[0].x} ${corners[0].y}`;
d += `L${corners[0].x} ${sides.top}`;
d += `L${corners[1].x} ${sides.top}`;
d += `L${corners[1].x} ${corners[1].y}`;
d += `L${sides.right} ${corners[1].y}`;
d += `L${sides.right} ${corners[2].y}`;
d += `L${corners[2].x} ${corners[2].y}`;
d += `L${corners[2].x} ${sides.bottom}`;
d += `L${corners[3].x} ${sides.bottom}`;
d += `L${corners[3].x} ${corners[3].y}`;
d += `L${sides.left} ${corners[3].y}`;
d += `L${sides.left} ${corners[0].y}z`;
path.setAttribute('d', d);
}
render();
function getClosest(x, y, r) {
const closest = corners.reduce((acc, val) => {
if ((val.x - x) ** 2 + (val.y - y) ** 2 < (acc.x - x) ** 2 + (acc.y - y) ** 2) {
return val;
}
return acc;
});
const isDragArea = (closest.x - x) ** 2 + (closest.y - y) ** 2 <= r ** 2;
return isDragArea ? closest : null;
}
let dragCorner = null;
svg.addEventListener('mousedown', (event) => {
dragCorner = getClosest(event.offsetX, event.offsetY, dragRadius);
});
svg.addEventListener('mouseup', () => {
dragCorner = null;
});
svg.addEventListener('mousemove', (event) => {
if (dragCorner) {
dragCorner.x = event.offsetX;
dragCorner.y = event.offsetY;
render();
}
else {
const closest = getClosest(event.offsetX, event.offsetY, dragRadius);
svg.style.cursor = closest ? 'pointer' : 'default';
}
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.