Получить абсолютные координаты элемента внутри SVG, используя JS - PullRequest
0 голосов
/ 05 декабря 2018

Доброго времени суток форумчанам.Я заранее прошу прощения за мой английский.Я не смог найти ответ (я решил спросить англоязычную аудиторию).

Абсолютное позиционирование (координаты) элемента, вложенного в группы относительно родительского контейнера ().

<svg width="100%" height="100%" viewBox="0 0 1000 1000" preserveAspectRatio="xMidYMin slice" x="0" y="0" tabindex="1">
  <g transform="translate(100 100)">
       <g transform="translate(100 100)"> 
            <circle r="50" cx="25" cy="25" fill="yellow" />
       </g>
  </g>
<svg>

Я бы хотел использовать координаты окружности ES6 + относительно SVG.То есть x = 100 + 100 + 25, y = 100 + 100 + 25 для.

Как я могу получить эти координаты?(может быть до бесконечного вложения групп).Спасибо за помощь.

enter image description here

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Получите потомков и родителей сверху и слева и получите разницу

const circleLeft = circleElement.getBoundingRect().offsetLeft
const circleTop = circleElement.getBoundingRect().top
const parentLeft = circleElement.parentElement.getBoundingRect().offsetLeft
const parentTop = circleElement.parentElement.getBoundingRect().top
const changeInX = parentLeft - cirleLeft
const changeInY = parentTop - circleTop

Если вы регистрируете события для этих элементов, зарегистрируйте их как событие захвата, а не всплывающее событие, передав true в качестве третьего аргументадо addEventListener

0 голосов
/ 05 декабря 2018
  1. Найдите значения cx и cy круга
  2. Примените любое преобразование, которое имеет круг
  3. Подойдите к каждому элементу-предку и примените все найденные преобразования
  4. Остановка при достижении корневого элемента SVG

function getCirclePosition(circleElemId)
{
  var elem = document.getElementById(circleElemId);
  var svg = elem.ownerSVGElement;

  // Get the cx and cy coordinates
  var pt = svg.createSVGPoint();
  pt.x = elem.cx.baseVal.value;
  pt.y = elem.cy.baseVal.value;

  while (true)
  {
    // Get this elements transform
    var transform = elem.transform.baseVal.consolidate();
    // If it has a transform, then apply it to our point
    if (transform) {
      var matrix = elem.transform.baseVal.consolidate().matrix;
      pt = pt.matrixTransform(matrix);
    }
    // If this element's parent is the root SVG element, then stop
    if (elem.parentNode == svg)
      break;
    // Otherwise step up to the parent element and repeat the process
    elem = elem.parentNode;
  }
  return pt;
}


var pos = getCirclePosition("thecircle");
console.log("Coordinates are: " + pos.x + "," + pos.y);
<svg width="100%" height="100%" viewBox="0 0 1000 1000" preserveAspectRatio="xMidYMin slice" x="0" y="0" tabindex="1">
  <g transform="translate(100 100)">
       <g transform="translate(100 100)"> 
            <circle id="thecircle" r="50" cx="25" cy="25" fill="yellow" />
       </g>
  </g>
<svg>

Обновление

Как указал @ Vad0k, существует более простой, но немного менее точный подход, который можетиспользовать вместо:

function getCirclePosition(circleElemId)
{
  var elem = document.getElementById(circleElemId);
  var svg = elem.ownerSVGElement;

  // Get the cx and cy coordinates
  var pt = svg.createSVGPoint();
  pt.x = elem.cx.baseVal.value;
  pt.y = elem.cy.baseVal.value;

  return pt.matrixTransform(getTransformToElement(elem, svg));
}


function getTransformToElement(fromElement, toElement) {
  return toElement.getCTM().inverse().multiply(fromElement.getCTM());
};


var pos = getCirclePosition("thecircle");
console.log("Coordinates are: " + pos.x + "," + pos.y);
<svg width="100%" height="100%" viewBox="0 0 1000 1000" preserveAspectRatio="xMidYMin slice" x="0" y="0" tabindex="1">
  <g transform="translate(100 100)">
       <g transform="translate(100 100)"> 
            <circle id="thecircle" r="50" cx="25" cy="25" fill="yellow" />
       </g>
  </g>
<svg>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...