繁体   English   中英

使用getCTM理解SVG变换矩阵

[英]Making Sense of SVG Transform Matrices Using getCTM

我一直在对我的SVG元素使用简单的transform translate 现在,我正在将转换转换为矩阵(并在此过程中拉动我的头发)。

SVG元素上, click ,我渲染一个元素,并基于当前pageX和pageY(鼠标坐标)进行简单的转换转换。

<svg width="1366" height="612" class="svg" viewBox="-78.48 43.82 752.30 337.05" xmlns="http://www.w3.org/2000/svg">
  <g class="elementParent">
    <g id="cry20Cyc_0.d7h" class="ele" data-action="ele" transform="translate(269.013,169.974)">
      <rect x="0" y="0" width="44" height="44" opacity="1" fill="#d1d1d1" stroke-width="1" vector-effect="non-scaling-stroke" class="selectRect"></rect>
      <path d="M0,22c0,12.2,9.9,22,22,22s22-9.8,22-22S34.2,0,22,0S0,9.9,0,22" fill="#482956"></path>
    </g>
  </g>
</svg>

注意g上的translate(269.013,169.974)。 当我调用getCTM() ,我得到了这个相当便宜的值:

  SVGMatrix { a: 1.8157544136047363, b: 0, c: 0, d: 1.8157544136047363, e: 630.9659423828125, f: 229.06468200683594 }

根据我的理解,矩阵“ a”和“ d”中的值表示缩放比例。 但是,我尚未应用任何缩放比例,此值来自何处?

当我在元素上运行transform时。 转换数组返回的值更合理:

SVGAnimatedTransformList { 
  baseVal: SVGTransformList[1], // {a:1 b:0 c:0 d:1 e:269.013 f:169.974} 
  animVal: SVGTransformList[1] }

我的假设是正确的,即getCTM可能getCTM viewbox值合并到getCTM的总输出中?

我的主要问题是,考虑到存在pageY viewbox ,并且在转换前必须将元素缩放为大小,我如何才能将鼠标位置pageX pageY转换为元素的正确矩阵值。

更新 :我发现是的, getCTM确实合并了getCTM值以返回CTM。 回想起来,这很有意义。 现在,如果有人可以帮助将鼠标坐标和比例合并到getCTM输出中的数学运算,那就太好了:)

我知道这有点晚了,但是最近有一个类似的问题引起了我的注意。 我修改了原始getCTM的返回值,并将其添加到原型中,如下所示:

!function(prt){
    prt._getAbsoluteCTM = function(){
        var owner = this.ownerSVGElement || this,
            height = owner.height.baseVal.value,
            width = owner.width.baseVal.value,
            viewBoxRect = owner.viewBox.baseVal,
            vHeight = viewBoxRect.height,
            vWidth = viewBoxRect.width;
        if(!vWidth || !vHeight){
            return this.getCTM();
        }
        var sH = height/vHeight,
            sW = width/vWidth,
            matrix = owner.createSVGMatrix();
        matrix.a = sW;
        matrix.d = sH
        var realCTM = this.getCTM().multiply(matrix.inverse());
        realCTM.e = realCTM.e/sW + viewBoxRect.x;
        realCTM.f = realCTM.f/sH + viewBoxRect.y;
        return realCTM;
    }
}(SVGGraphicsElement.prototype);

用法是: element._getAbsoluteCTM()并确保在绘制之前包括该polyfill。

如果检测到viewBox属性,它将返回“绝对CTM”,否则将返回与element.getCTM相同的值element.getCTM

这是一个最小的示例,您可以在检查器上使用它的值: https : //jsfiddle.net/ibowankenobi/1mmh7rs6/6/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM