Javascript 获取svg元素的全局变换矩阵

Javascript 获取svg元素的全局变换矩阵,javascript,svg,Javascript,Svg,我想使用浏览器svg+JavaScript从用户准备的svg模板(例如,在Inkscape中创建的模板)生成动态图像,其中有矩形占位符标记动态图形应该放置的位置 理想情况下,应该允许用户(模板创建者)以任何方式移动、缩放、旋转和倾斜矩形(倾斜后没有那么多矩形)。他们必须做的唯一一件事是为那些占位符矩形设置正确的id值 我正在寻找一种方法,如何获得/计算这些占位符的变换矩阵。由于它们可以嵌套在组中,因此仅读取元素的属性是不够的。SVG命令getCTM和/或getScreenCTM可能就是您要查找的

我想使用浏览器svg+JavaScript从用户准备的svg模板(例如,在Inkscape中创建的模板)生成动态图像,其中有矩形占位符标记动态图形应该放置的位置

理想情况下,应该允许用户(模板创建者)以任何方式移动、缩放、旋转和倾斜矩形(倾斜后没有那么多矩形)。他们必须做的唯一一件事是为那些占位符矩形设置正确的id值


我正在寻找一种方法,如何获得/计算这些占位符的变换矩阵。由于它们可以嵌套在组中,因此仅读取元素的属性是不够的。

SVG命令
getCTM
和/或
getScreenCTM
可能就是您要查找的。(我相信CTM代表“当前转换矩阵”)您可以使用它们,例如,通过jQuery检索元素,剥离封闭的jQuery对象并调用命令,例如
$(“#mySvgCircleId”)[0]。getScreenCTM()
。它们都返回SVG矩阵对象。两者都将为您提供矩阵信息,其中考虑到它们自己的直接转换以及应用于形状嵌套的任何父svg元素的任何转换。听起来像是你在找的

但是,请注意,这两个命令之间有重要的区别。我将在下面的代码片段中演示其中的一些差异。在这里我显示了两个
svg
元素,一个带有两个红色矩形,一个带有两个蓝色矩形。所有矩形都具有相同的宽度和高度,但每种颜色中的一种未转换,而另一种嵌套在三个不同转换的组中。输出使用每个矩形的
getCTM
getScreenCTM
显示矩阵结果。注意以下几点:

  • getCTM
    getScreenCTM
    都考虑到任何封闭的祖先元素的转换,例如任何
    g
    组元素,直到封闭的
    svg
    元素。e、 g.两个命令的“untransformedlect1”和“transformedlect1”返回的矩阵不同
  • getCTM
    结果不受封闭的
    svg
    元素在其父元素中的位置的影响,而
    getScreenCTM
    结果不受影响。e、 g.使用
    getCTM
    时,“untransformedRect1”和“untransformedRect2”的结果相同,但使用
    getScreenCTM
    时结果不同
例如,如果您正在处理iframe,将svg元素嵌套在其他svg元素中,等等,那么可能会有更多的复杂情况,我在这里不讨论这些问题

var infoType=“CTM”;
显示(“来自getCTM()的矩阵结果”);
显示(getInfo(信息类型,“untransformedRect1”);
显示(getInfo(信息类型,“transformedRect1”);
显示(getInfo(信息类型,“untransformedRect2”);
显示(getInfo(信息类型,“transformedRect2”);
显示(
); var infoType=“ScreenCTM”; 显示(“getScreenCTM()的矩阵结果”); 显示(getInfo(信息类型,“untransformedRect1”); 显示(getInfo(信息类型,“transformedRect1”); 显示(getInfo(信息类型,“untransformedRect2”); 显示(getInfo(信息类型,“transformedRect2”); 函数getInfo(mtrx,id){ var-mtrx; 如果(信息类型==“CTM”){ var mtrx=$(“#”+id)[0].getCTM(); }else if(信息类型==“ScreenCTM”){ var mtrx=$(“#”+id)[0]。getScreenCTM(); } var-str= r(mtrx.a)+“,”+ r(mtrx.b)+“,”+ r(mtrx.c)+“,”+ r(mtrx.d)+“,”+ r(mtrx.e)+“,”+ r(mtrx.f); 返回id+”:矩阵:“+str; } 函数r(num){ 返回数学整数(num*1000)/1000; } 功能显示(msg){ 文件。写(msg+“
”); }

根据查看方式,可能需要向下滚动查看矩阵值


移位==>

不幸的是,Chrome不再支持这个很酷的功能了:这真是太糟糕了,因为我很兴奋能找到这个功能。这将使在大量分组的svg图像中进行操作变得更加容易。哦,好吧。非常感谢您提供的信息。对于不支持该函数的浏览器(愚蠢的chrome…)SVGElement.prototype.getTransferorMToElement=SVGElement.prototype.getTransferorMToElement | | |函数(toElement){return-toElement.getScreenCTM().inverse().multiply(this.getScreenCTM());}@JasonCrist,这是一个很好的填充,谢谢!不过我担心。对于尚未由特定浏览器实现的功能,通常存在多边形填充。这是针对一个已经实现,然后被主动删除的特性。这是否代表了从所有浏览器中删除此功能的更广泛趋势中的后台对话?如果是这样的话,那么在某种程度上,这种多面体可能是不值得战斗的艰苦战斗。然而,如果至少
getScreenCTM
还在这里,那么您的解决方案肯定还是有价值的。