Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the current matrix transformation of an SVG element

I know a very easy way to get the current matrix transformation of any SVG element:

// 't' is a string
var t = window.getComputedStyle(nativeElement, null).transform
console.log(t);

The problem is that the previous method returns numbers with no more than six decimals. For example, the previous code may return:

matrix(0.965926, 0.258819, -0.258819, 0.965926, 0, 0)

Is there a way to get the matrix transformation of any SVG element more accurately?

like image 566
Cequiel Avatar asked Sep 26 '17 19:09

Cequiel


3 Answers

To get the current transform attribute as an SVGMatrix object, you can use:

element.transform.baseVal.consolidate().matrix

var myrect = document.getElementById("myrect");

console.log(myrect.transform.baseVal.consolidate().matrix);
<svg>
  <rect id="myrect" width="10" height="10" transform="scale(2) rotate(45)"/>
</svg>
like image 129
Paul LeBeau Avatar answered Oct 07 '22 09:10

Paul LeBeau


Consolidation can change your element 'transform' attribute value. You can also get a matrix without changing the transformation attribute by transforming the element matrix to the parent.

See documentation about the:

getTransformToElement

function getMatrix(element) {
  var matrix = element.parentNode
     .getScreenCTM()
     .inverse()
     .multiply(element.getScreenCTM());
  return matrix;
}
var myrect = document.getElementById("myrect");

console.log(getMatrix(myrect));
<svg>
  <rect id="myrect" width="10" height="10" transform="scale(2) rotate(45)"/>
</svg>
like image 26
Ievgen Avatar answered Oct 07 '22 09:10

Ievgen


In the case if you know that your SVG element has no ancestors wich were transformed you can use SVGelement.getCTM() function for it because it is shorter. I think that CTM in the function name is the short form from «current transformation matrix».

var rect = document.querySelector("#rect");

console.log(rect.getCTM());
<svg>
    <rect id="rect" width="10" height="10" transform="scale(2) rotate(45)"/>
</svg>

Difference rect.getCTM() vs. rect.transform.baseVal.consolidate().matrix

But you should be careful about the use from this function because it only gives the same result like from the matrix rect.transform.baseVal.consolidate().matrixas long as no ancestor elements have a transform. For example:

var rect = document.querySelector("#rect"),
    ctmMatrix = rect.getCTM(),
    baseValMatrix = rect.transform.baseVal.consolidate().matrix;

console.log('CTM Matrix: translateX = '+ctmMatrix.e+', translateY = '+ctmMatrix.f);
console.log('BaseVal Matrix: translateX = '+baseValMatrix.e+', translateY = '+baseValMatrix.f);
<svg>
    <g transform="translate(35,45)">
        <rect id="rect" width="10" height="10" transform="translate(35,45)"/>
    </g>
</svg>

I thank @PaulLeBeau for the explanation about the difference between this matrixes.

like image 25
Bharata Avatar answered Oct 07 '22 08:10

Bharata