Home > Software engineering >  Where can I find transform-origin's definition and how does transform-origin work?
Where can I find transform-origin's definition and how does transform-origin work?

Time:01-10

I have a simple html with svg as below:

<svg  style="border:1px solid black" width="200" height="200">
  <rect transform="translate(100, 100)" width="20" height="20" fill="red"></rect>
  <text transform="translate(100, 100) rotate(90)" transform-origin="0 0">TEST</text>
</svg>

The text element is rotated 90 degree in clockwise base on text's left-bottom corner (left-upper corner of red rect)

If I change text element to <text x="50" y="50" transform="translate(50, 50) rotate(90)" transform-origin="0 0">TEST</text>, the text is rotated to (0, 100) in svg. A reasonable guess is that transform-origin does not only affect "rotate" but also "translate". But I don't understand where "0 0" is in this situation, but it is not left-bottom corner of text element anymore.

I also don't understand how it works when I set "transform-origin" in percentage (e.g. 50% 50%) or text (e.g. left bottom). It doesn't work the way I thought it would. I have not been able to find a detailed tutorial on the definition of "transform-origin". Can someone with experience in this field give me some pointers? Thanks!

CodePudding user response:

It is always easier in SVG contexts to read transformations as transformations of the coordinate system. Each of the steps builds on its predecessor. Your element

<text x="50" y="50" transform="translate(50, 50) rotate(90)" transform-origin="0 0">TEST</text>

can be understood as the following sequence:

  • translate(50, 50): Move the origin of the coordinate system to (50, 50) of the initial coordinate system
  • rotate(90) and transform-origin="0 0": Rotate the coordinate system found in the previous step by 90° clockwise around its own origin.
  • text x="50" y="50": Draw text at point (50, 50) of the coordinate system found in the previous step.

In relation to the initial coordinate system, the last one has its origin at (50, 50), the x-axis points left and the y-axis down. The blue lines show its position and orientation. Therefore, the point (50, 50) in that system is the same as (0, 100) in the initial coordinate system:

<svg  style="border:1px solid black" width="200" height="200">
  <rect transform="translate(100, 100)" width="20" height="20" fill="red"></rect>
  <text x="50" y="50" transform="translate(50, 50) rotate(90)" transform-origin="0 0">TEST</text>
  <!-- draw the moved coordinate system -->
  <path transform="translate(50, 50) rotate(90)" transform-origin="0 0"
        d="M-5,0H100M0,-5V100" fill="none" stroke="blue" />
</svg>

So why does transform-origin="0 0" refer to the coordinate system? The CSS Transforms specification says:

The value for the horizontal and vertical offset represent an offset from the top left corner of the reference box.

The reference box is defined by property transform-box. If not explicitely set, its initial value is view-box:

Uses the nearest SVG viewport as reference box.

In your case, this is the box that defines the <svg> element and outlined by the black border, but with the defined sequence of transforms applied. (If there was a viewBox attribute present, it would represent a further implicit transform, to be applied first.)

  • Related