Думайте о SVG как о дереве вложенных систем координат. Каждый элемент имеет свои собственные координаты и вписывает в свой родительский элемент правило, как их пересчитывать. Эти правила могут быть как явными transform
атрибутами, так и неявными комбинациями width
, height
и viewBox
("вписать поле A в размер B").
Атрибут transform
считается ссылкой на родительский элемент. Это означает, что если вы запрашиваете геометрическое свойство элемента, в большинстве случаев вы получаете значение до , когда применяется преобразование. После это будет означать запрос геометрических значений в системе координат родителя.
Из-за этой сложности есть несколько функций API SVG, чтобы выяснить, как эти системы координат сочетаются друг с другом. getPointAtLength()
возвращает ваши координаты до применения атрибута transform
.
var localPoint = path.node().getPointAtLength(0)
Сначала вы должны выяснить, что делает атрибут transform
. Это выглядит немного сложно, отчасти потому, что атрибут может быть анимирован и может содержать список функций, отчасти потому, что API ... ну ...:
// construct a neutral matrix
var localMatrix = path.node().viewportElement.createSVGMatrix()
var localTransformList = path.node().transform.baseVal
// is there at least one entry?
if (localTransformList.length) {
// consolidate multiple entries into one
localMatrix = localTransformList.consolidate().matrix
}
Затем вы можете применить найденное преобразование к точке с помощью
var transformedPoint = localPoint.matrixTransform(localMatrix)
Существует несколько функций, которые возвращают SVGMatrix
для преобразования данных из системы координат после применения атрибута transform
(т.е. после шага, описанного выше):
, чтобы запросить преобразование к ближайшему элементу области просмотра (в большинстве случаев к ближайшему родительскому элементу <svg>
): element.getCTM()
чтобы запросить преобразование в пиксели экрана: element.getScreenCTM()
, чтобы запросить преобразование в произвольный элемент: element.getTransformToElement(...)