inset.mjs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. function calcInset(element, container) {
  2. const inset = { x: 0, y: 0 };
  3. let current = element;
  4. while (current && current !== container) {
  5. if (current instanceof HTMLElement) {
  6. inset.x += current.offsetLeft;
  7. inset.y += current.offsetTop;
  8. current = current.offsetParent;
  9. }
  10. else if (current.tagName === "svg") {
  11. /**
  12. * This isn't an ideal approach to measuring the offset of <svg /> tags.
  13. * It would be preferable, given they behave like HTMLElements in most ways
  14. * to use offsetLeft/Top. But these don't exist on <svg />. Likewise we
  15. * can't use .getBBox() like most SVG elements as these provide the offset
  16. * relative to the SVG itself, which for <svg /> is usually 0x0.
  17. */
  18. const svgBoundingBox = current.getBoundingClientRect();
  19. current = current.parentElement;
  20. const parentBoundingBox = current.getBoundingClientRect();
  21. inset.x += svgBoundingBox.left - parentBoundingBox.left;
  22. inset.y += svgBoundingBox.top - parentBoundingBox.top;
  23. }
  24. else if (current instanceof SVGGraphicsElement) {
  25. const { x, y } = current.getBBox();
  26. inset.x += x;
  27. inset.y += y;
  28. let svg = null;
  29. let parent = current.parentNode;
  30. while (!svg) {
  31. if (parent.tagName === "svg") {
  32. svg = parent;
  33. }
  34. parent = current.parentNode;
  35. }
  36. current = svg;
  37. }
  38. else {
  39. break;
  40. }
  41. }
  42. return inset;
  43. }
  44. export { calcInset };