SVG 绝对坐标?

发布于 2024-08-09 06:28:59 字数 390 浏览 7 评论 0原文

我有一些 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>

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

谢谢!

I have some SVG files which have many text nodes in them.

I would like to get the absolute position of each of the text nodes, within the SVG document (the SVG documents have width="743.75" and height="1052.5").

An example text node looks like this:

 <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>

How can I calculate all of the matrix() transforms to arrive at the positive absolute X and Y values for each text box? Is there a simple recursive function I could use and pass in each matrix in turn?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暖心男生 2024-08-16 06:28:59

我也在尝试解决这个问题,除了图像。递归的问题是你需要对变换矩阵进行点乘。我正在使用 NumPy。然而,我的计算得出了表面上不正确的答案。也许你会有更多的运气。

链接

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)

I am also trying to solve this problem, except for images. The question of recursion is that you need to dot multiply the transformation matricies. I'm using NumPy. However, my computations are coming up with ostensibly incorrect answers. Maybe you'll have more luck.

Link

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)
夜深人未静 2024-08-16 06:28:59

我没有太多时间来完善这个答案,但这对我来说很有用,可以将 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 位置到一个绝对的位置

希望它可以帮助任何人在未来

保持祝福

I dont have much time to refine this answer, but this worked for me to convert svg coordinates to an absolute position

//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
    };
},

and to actually use the code to do useful stuff:

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

where mysvg is the container element. i.e.

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

allCircleElements[0] is the actual element to allCircleElements[0].getBBox().x is the x position that will be converted later to an absolute position and finally, the last parameter (i.e. 0) is the y position to be converted to an absolute position

hope it helps anyone in the future

stay blessed

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文