SVG transformations

When you use SVG it is possible to transform created shapes. In the SVG 'use' element page you saw that you can change x and y coordinates of the <use> element and place graphics at a specified location (at new coordinates). New x and y coordinates define the upper left corner of the graphics to be drawn.

One more and mostly used method is to make transformations via transform attribute. The following transform definitions are available:

  • matrix (a,b,c,d,e,f) specifies a transformation in the form of a transformation matrix of six values. Find more informations about this matrices at the W3C SVG 1.1 recommendation.
  • translate(tx, [ty]) specifies a translation by tx and ty. ty is optional, if it is not specified, it is assumed to be zero. tx and ty are the distances to translate respectively x and y coordinates.
  • scale(sx, [sy]) specifies a scale operation by sx and sy. If sy is not provided, it is assumed to be equal to sx. x and y coordinates in the new coordinate system equals respectively sx and sy units in the previous coordinate system.
  • rotate(rotate-angle, [], []) which specifies a rotation by rotate-angle degrees about a given point. cx and cy are optional parameters, if they are not set, the rotate applies to the current user coordinate system. If these parameters are specified, the rotate is concerned the point (cx, cy).
  • skewX(skew-angle) and skewY(skew-angle) specify a skew transformation of x or y coordinate by angle a respectively.

Here are several rules according to the usage of the transform attribute:

  • If you set a list of transforms, then each transform is applied in the order provided.
  • The transform attribute is applied to an element before processing any other coordinate or length values supplied for that element. All attributes (x, y, width, height and other) are treated as values in the new user coordinate system.

Here are several examples:

  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
	  <defs>
		  <g id="rect" fill="lightgrey" stroke="black" stroke-width="2">
			  <rect x="10" y="10" width="30" height="30"/>
		  </g>
	  </defs>
	
	  <!--Here 2 rectangles are drawn to see the effect--/>
	
	  <use xlink:href="#rect"/> 
	  <use xlink:href="#rect" transform="scale(2)"/>	
  </svg>
							

As you can see the new rectangle is moved. Actually, it's not. We have just change the coordinate system - the (0, 0) point of the coordinate system is still in the same place, but each user coordinate is now twice as large as it used to be.

The source code for this image is almost the same, except for the transform attribute. It's set to the following value: transform="scale(2, 3)". Different scale options for x and y coordinates are used.
  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="-40 0 110 180">
	  <defs>
		  <g id="rect" fill="lightgrey" stroke="black" stroke-width="2">
			  <rect x="50" y="20" width="50" height="30"/>
		  </g>
	  </defs>
	
	  <!--Here 2 rectangles are drawn to see the effect--/>
	
	  <use xlink:href="#rect"/> 
	  <use xlink:href="#rect" transform="rotate(45)"/>	
  </svg>
							

In this example the cetre of the rotation is not specified so it is presumed to be (0,0).

The transform attribute is set to the following value: transform="rotate(45, 50, 50)". Thus the centre of the rotation is (50,50).
  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="-40 0 110 180">
	  <defs>
		  <g id="rect" fill="lightgrey" stroke="black" stroke-width="1">
			  <rect x="10" y="10" width="30" height="30"/>
		  </g>
	  </defs>
	
	  <!--Here 2 rectangles are drawn to see the effect--/>
	
	  <use xlink:href="#rect"/> 
	  <use xlink:href="#rect" transform="translate(40,10)"/>	
  </svg>
							

In this example the shape (rectangle) is moved 40 pixels in the x-direction and 10 pixels in the y-direction.

	<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="-40 0 110 180">
		<defs>
			<g id="line">
				<line x1="10" y1="10" x2="60" y2="10" />
				<line x1="10" y1="10" x2="10" y2="60" />
			</g>
		</defs>
	
		<!--Here 2 line groups are drawn to see the effect--/>
	
		<use xlink:href="#line" stroke="grey" stroke-width="2" /> 
		<use xlink:href="#line" transform="skewX(45)" stroke="red" stroke-width="1" />	
	</svg>
							

In this example all x coordanates are skewed by an angle of 45 degrees.