我能获取 SVG 对象的翻译/缩放吗?

4
我正在编写一个符号识别服务,希望将其扩展为完整的公式识别。这样,用户可以编写公式并获得LaTeX格式的输出。当用户完成编写时,我会将编写的内容作为SVG存储在模板中。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   version="1.1"
   width="400"
   height="400"
   xml:space="preserve"
   viewBox="0 0 {{ width }} {{ height }}"
   preserveAspectRatio="xMidYMid meet">

{{ path }}
{{ dots }}
</svg>

这是通过

包含的内容


<object data="123456.svg"
        type="image/svg+xml"
        id="canvas"
        style="width:400px;height:400px;border:1px solid black;"></object>

(请参见没有居中的旧模板示例
现在我有一些JavaScript代码,允许用户对公式进行分段。但是当SVG使用viewBox / preserveAspectRatio自我居中时,需要调整此代码。
如何获取必要的值(平移和缩放因子)来调整我的代码?
(我发现MDN SVG Svg DOM接口,但是当我在对象标记中包含svg时,似乎无法工作。我不能将svg包含在图像标记中,因为我需要处理SVG内容。)
1个回答

1

SVG元素有一个名为getScreenCTM()的函数,它返回用于将SVG空间中的坐标转换为屏幕空间中的坐标的矩阵。

你想要相反的方向。幸运的是,所有的SVGMatrix对象都有一个名为inverse()的函数,可以反转矩阵。

你需要做的就是获取鼠标事件中的clientXclientY坐标,并通过反转后的矩阵运行它们。然后你就会得到该点对应的SVG坐标。

<html>

<object data="324196.svg"
        type="image/svg+xml"
        id="canvas"
        style="width:400px;height:400px;border:1px solid black;" onclick="calc()"></object>

</body>

<script>

canvas.addEventListener("load",function(){
   document.getElementById("canvas").contentDocument.addEventListener("click", calc);
});

function calc(evt)
{
    var svg = document.getElementById("canvas").contentDocument.firstChild;

    var  point = svg.createSVGPoint();
    point.x = evt.clientX;
    point.y = evt.clientY;
    point = point.matrixTransform(svg.getScreenCTM().inverse());

    var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
    circle.setAttribute("cx", point.x);
    circle.setAttribute("cy", point.y);
    circle.setAttribute("r", "5");
    circle.setAttribute("fill", "red");
    circle.setAttribute("fill-opacity", "0.5");
    svg.appendChild(circle);
}

</script>

</html>

另外,对于您的 getContainedPaths() 函数,如果您调用 paths[i].getBBox(),您可能会发现返回结果很有用。 :) - Paul LeBeau
你是指获得“已接受”的绿色勾号和/或赞同吗?这总是更好的选择。但你不能强迫别人这样做,所以当他们不这样做时生气是没有意义的。回答问题并不是我来这里的主要原因。 - Paul LeBeau
我的大部分答案都在SVG标签中。这不是一个会产生很多积分或徽章的标签。 :) - Paul LeBeau
不,我不是指接受/点赞。我是指悬赏。偶尔我会给那些回答快速且优秀的人们发放悬赏(在接受和点赞之后),以表达我对他们所写内容的感激之情。然而,对于像你这样拥有超过10k积分的人来说,我不确定他们是否真的在意获得悬赏。 - Martin Thoma
很遗憾,不是完全可以。SO只允许我在2天后给出赏金。希望我不会忘记它。 - Martin Thoma
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接