SVG绝对坐标?

时间:2009-10-27 16:20:46

标签: svg coordinates relative absolute

我有一些SVG文件,里面有很多文本节点。

我想在SVG文档中获取每个文本节点的绝对位置(SVG文档的宽度=“743.75”,高度=“1052.5”)。

示例文本节点如下所示:

 <g>
  <text transform="matrix(1,0,0,-1,106.5,732.5)">
   <tspan x="0 7.8979998 14.003 17.698999" y="0">Date</tspan>
  </text>
 </g>

如何计算所有矩阵()变换以获得每个文本框的正绝对X和Y值?是否有一个简单的递归函数我可以使用并依次传入每个矩阵?

谢谢!

2 个答案:

答案 0 :(得分:1)

我也试图解决这个问题,除了图像。递归的问题是你需要点乘变换矩阵。我正在使用NumPy。但是,我的计算结果表面上是错误的答案。也许你会有更多的运气。

http://www.scipy.org/Tentative_NumPy_Tutorial

http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined

from decimal import Decimal
import xml.dom.minidom as dom
from numpy import *
doc = dom.parse("labels.svg")

def walk(node):
    if node.nodeType != 1:
        return
    if node.tagName == 'image':
        href = node.getAttribute('xlink:href')
        if not href.startswith("labels/"):
            return
        name = (
            href.
            replace('labels/', '').
            replace('.png', '').
            replace('-resized', '').
            replace('-normalized', '')
        )
        left = float(node.getAttribute('x'))
        top = float(node.getAttribute('y'))
        position = matrix([left, top, float(1)])
        width = float(node.getAttribute('width'))
        height = float(node.getAttribute('height'))
        size = matrix([left, top, float(1)])
        transform = node.getAttribute('transform')
        if transform:
            a, b, c, d, e, f = map(float, transform
                .replace('matrix(', '')
                .replace(')', '')
                .split(',')
            )
            transform = matrix([
                [a, c, e],
                [b, d, f],
                [0, 0, 1]
            ])
            left, top, _ = (transform.I * position.T).A1
        print name, (left, top)
    child = node.firstChild
    while child:
        walk(child)
        child = child.nextSibling

walk(doc.documentElement)

答案 1 :(得分:0)

我没有太多时间来完善这个答案,但这对我来说是有效的将svg坐标转换为绝对位置

//this will convert an x, y coordinate within a viewBox - or not in one at all (I think) - to an absolute position on the document
//my <svg>...</svg> element had a viewbox on it and it still worked...
convertCoords: function(svgElement, elementToConvert, x, y) {

    var element_x = elementToConvert.getBBox().x;
    var element_y = elementToConvert.getBBox().y;
    var offset = svgElement.getBoundingClientRect();
    var matrix = elementToConvert.getScreenCTM();

    return {
        x: (matrix.a * x) + (matrix.c * y) + matrix.e - offset.left,
        y: (matrix.b * x) + (matrix.d * y) + matrix.f - offset.top
    };
},

并实际使用代码来做有用的事情:

svgGraphLibObject.convertCoords(mysvg, allCircleElements[0], allCircleElements[0].getBBox().x, 0)

其中mysvg是容器元素。即。

var mysvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');

allCircleElements [0]是allCircleElements [0] .getBBox()的实际元素.x是稍后将转换为绝对位置的x位置,最后,最后一个参数(即0)是y位置被转换为绝对位置

希望它能帮助将来的任何人

保持幸福