Skip to content

Instantly share code, notes, and snippets.

@mr-moon
Created November 18, 2019 11:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mr-moon/783371e8b785d73c71c6c31781db0fdb to your computer and use it in GitHub Desktop.
Save mr-moon/783371e8b785d73c71c6c31781db0fdb to your computer and use it in GitHub Desktop.
DOM element coordinate helpers
/**
* MIT License
* @author Alexander Moon mainarx@gmail.com
*/
/**
* An offset type definition
* @typedef {Object} Offset
* @property {number} top
* @property {number} left
*/
/**
* A point type defition
* @typedef {Object} Point
* @property {number} x
* @property {number} y
*/
/**
* An offset getter. Optionally gets an offset relative to given parent node
* @param {HTMLElement} el - Target element, that offset is going to be
* calculated for
* @param {HTMLElement} [parent] - Relative element
* @return Offset
*/
function offset(el, parent = null) {
var top = 0,
left = 0;
if (el.offsetParent) {
do {
top += el.offsetTop;
left += el.offsetLeft;
}
while ((el = el.offsetParent));
if (parent && document.body.contains(parent)) {
var local = globalToLocal(parent, left, top);
return {
top: local.y,
left: local.x
}
}
return {top: top, left: left};
}
}
/**
* Function that converts a point in element's coordinate space to document's
* @param {HTMLElement} el An element to base coordinates off
* @param {number} lx Local X coordinate, within el-s coordinate space
* @param {number} ly Local Y coordinate, within el-s coordinate space
* @return Point
*/
function localToGlobal(el, lx, ly) {
var op = offset(el);
return ({
x: Math.floor(lx + op.left),
y: Math.floor(ly + op.top)
});
}
/**
* Function that converts a point in documents's coordinate space to coordinate
* space of given element
* @param {HTMLElement} el An element to base coordinates off
* @param {number} gx Global X coordinate, within document's coordinate space
* @param {number} gy Global Y coordinate, within document's coordinate space
* @return Point
*/
function globalToLocal(el, gx, gy) {
var op = offset(el);
return {
x: Math.floor(gx - op.left),
y: Math.floor(gy - op.top)
}
}
/**
* Converts a point in coordinate space of source element, to a point in
* coordinate space of destination element. Useful when you need to relocate
* an element within DOM-tree, but keep it visually intact
* @param {HTMLElement} src HTML element to base off coordinates
* @param {HTMLElement} dest HTML element to do coordinate conversion for
* @param {number} lx Local x coordinate
* @param {number} ly Local y coordinate
* @return Point
*/
function localToLocal(src, dest, lx, ly) {
var srcOffset = offset(src),
destOffset = offset(dest);
return {
x: Math.floor(lx + srcOffset.left - destOffset.left),
y: Math.floor(ly + srcOffset.top - destOffset.top)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment