svgrotationtransformtranslate

SVG mutltiple transform - rotate then translate horizontally


Using an SVG I am trying to rotate it by 30 degrees and then translate that horizontally 100. The issue is that when I rotate the coordinate system, it is rotated and so when I try to translate I will be translating the object along the rotated x-axis which is now at 30 degrees to the horizontal.

Is there any way to translate horizontally after rotation?

<g transform="rotate(30 50 50) translate(100 0)">
   <rect x="0" y="0" fill="blue" width="100" height="100" />
</g>

I want to create control buttons for rotate and translate up, down, left, right. These will create a string which will use data binding to the transform property of the SVG and so transform the object sequentially. But the translations need to be relative to the viewport not how the object has been rotated.

I am using the Vue.js framework for the data binding. I also do not want to use CSS.


Solution

  • If you want the rotate to happen first, you have to put that last in your transform attribute.

    <g transform="translate(100 0) rotate(30 50 50)">
       <rect x="0" y="0" fill="blue" width="100" height="100" />
    </g>
    

    Why? Because the above snippet is equivalent to

    <g transform="translate(100 0)">
       <g transform="rotate(30 50 50)">
          <rect x="0" y="0" fill="blue" width="100" height="100" />
       </g>
    </g>
    

    You can think of transforms as happening from the inside out. The rectangle is affected by the inner rotate transform before the outer translate transform.

    Or to think of it another way, the outer transform creates a new coordinate system that is shifted 100 to the right. Within that there is a separate coordinate system that is rotated 30 degrees. Into that the rectangle is drawn.