svg: найти координаты x, y прямоугольных вершин - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть различные svg ректы на веб-странице, к которой применяется преобразование в форме:

    transform="translate(418 258) rotate(-45.2033 15 18) scale(2.5 2.5)"

Мне нужно получить координаты x, y 4 вершин каждого прямоугольника после применения преобразования.

Вот пример кода:

<g transform="translate(418 258) rotate(-45.25 15 18) scale(2.5 2.5)">
  <rect id="box" x="0" y="0" width="31" height="37" style="fill:none;stroke:rgb(102, 102, 102);stroke-width:1.5px;">
  </rect>
</g>

Я пробовал следующую формулу в простой js:

x' = x * cos(angle) + y * sin(angle)
y' = -x * sin(angle) + y * cos(angle)

но результаты немного отличаются от отображения svg в различных браузерах.

Полагаю, это можно сделать с помощью примитивов js / svg, но я не знаю как и не нашел ни одного примера кода. Возможно, преобразование ректов в пути после трансформации поможет ...

И последнее, но не менее важное: я использую jquery, но не d3.

Заранее спасибо.

1 Ответ

0 голосов
/ 10 апреля 2019

Вы можете прочитать атрибут преобразования и преобразовать его в матрицу.Затем для каждого из четырех углов прямоугольника вы можете использовать эту матрицу для вычисления преобразованных угловых положений.

См. Следующую демонстрацию.

В этой демонстрации предполагается, что существует элемент с idиз "box", и что преобразование, о котором вы заботитесь, это просто преобразование в родительском элементе <g>.Если ваши обстоятельства более сложны, чем это, вам нужно будет еще немного поработать над этим кодом.

// Get a reference to the "box" rect element
var box = document.getElementById("box");
// Get its x, y, width and height
var bx = box.x.baseVal.value;
var by = box.y.baseVal.value;
var bw = box.width.baseVal.value;
var bh = box.height.baseVal.value;

// Get the box's parent element (the <g>)
var parentGroup = box.parentNode;
// Read the transform attribute and convert it to a transform matrix object
var transformMatrix = parentGroup.transform.baseVal.consolidate().matrix;

// For each of the rectangle's four corners, use the transform matrix to calculate its new coordinates
console.log("point 1 = ", doPoint(bx, by));
console.log("point 2 = ", doPoint(bx + bw, by));
console.log("point 3 = ", doPoint(bx + bw, by + bh));
console.log("point 4 = ", doPoint(bx, by + bh));



function doPoint(x, y)
{
  // We need a reference to the <svg> element for the next step
  var svg = box.ownerSVGElement;
  // Create an SVGPoint object with the correct x and y values
  var pt = svg.createSVGPoint();
  pt.x = x;
  pt.y = y;
  // Use the "matrixTransform()" method on SVGPoint to apply the transform matrix to the coordinate values
  pt = pt.matrixTransform(transformMatrix);
  // Return the updated x and y values
  return {x: pt.x, y: pt.y};
}
<svg>
  <g transform="translate(418 258) rotate(-45.25 15 18) scale(2.5 2.5)">
    <rect id="box" x="0" y="0" width="31" height="37" style="fill:none;stroke:rgb(102, 102, 102);stroke-width:1.5px;">
    </rect>
  </g>
</svg>
...