Understanding SVG Translate, Rotate, and Scale

This article explores how the Scalable Vector Graphics (SVG) coordinate transformation system processes translate, rotate, and scale operations. Instead of altering an element’s geometric definition directly, SVG transformations modify the element’s local coordinate system. Understanding this fundamental concept clarifies how visual shifts, resizing, and rotations take place relative to the canvas origin.

The SVG Coordinate System Foundation

The standard SVG viewport establishes a Cartesian coordinate system where the point (0, 0) resides in the top-left corner. The positive x-axis extends to the right, and the positive y-axis extends downward.

When you apply a transform attribute to an SVG element, you do not simply move the rendered pixels. Instead, you create a new, local coordinate space that is positioned, oriented, and scaled relative to its parent coordinate space. All shapes, strokes, and child elements are then rendered according to this newly transformed grid.

Translate: Shifting the Origin

The translate(tx, [ty]) function moves the coordinate system’s origin (0, 0) by tx units along the x-axis and ty units along the y-axis. If ty is omitted, it defaults to 0.

<g transform="translate(50, 100)">
  <rect x="0" y="0" width="40" height="40" />
</g>

In this example: * The origin of the <g> group is shifted 50 units right and 100 units down. * The rectangle’s (x, y) position of (0, 0) is evaluated within this new coordinate space, placing it visually at (50, 100) in the root viewport.

Scale: Resizing the Unit Grid

The scale(sx, [sy]) function multiplies the unit size along the x-axis by sx and the y-axis by sy. If sy is omitted, it assumes the value of sx, applying a uniform scale.

<g transform="scale(2, 2)">
  <rect x="10" y="10" width="20" height="20" stroke-width="2" />
</g>

Key behaviors of scale: * Grid Stretching: A scale factor of 2 doubles the size of every unit along that axis. * Position Scaling: The shape’s position (10, 10) is also multiplied by the scale factor, placing its top-left corner at (20, 20) relative to the parent space. * Stroke Scaling: Non-vector properties like stroke-width scale proportionally. A stroke-width="2" becomes 4 units wide unless vector-effect="non-scaling-stroke" is specified.

Rotate: Angling the Coordinate Axes

The rotate(angle, [cx, cy]) function rotates the coordinate system clockwise by the specified angle in degrees.

By default, rotation occurs around the current origin (0, 0):

<!-- Rotates 45 degrees around (0, 0) -->
<rect x="20" y="20" width="50" height="50" transform="rotate(45)" />

Because rotating around (0, 0) often swings elements off-screen or out of position, SVG provides optional center coordinates (cx, cy):

<!-- Rotates 45 degrees around (45, 45) -->
<rect x="20" y="20" width="50" height="50" transform="rotate(45, 45, 45)" />

Supplying cx and cy is shorthand for three separate operations executed in order: 1. translate(cx, cy) 2. rotate(angle) 3. translate(-cx, -cy)

Combining Transformations and Execution Order

Multiple transformations can be chained within a single transform attribute, separated by spaces or commas:

<rect transform="translate(100, 50) rotate(45) scale(1.5)" ... />

Transformations are processed sequentially from left to right. Each successive operation applies to the coordinate system created by the preceding transformation: 1. Translate: Moves the origin to (100, 50). 2. Rotate: Rotates the grid 45 degrees around the new origin. 3. Scale: Stretches the rotated grid by a factor of 1.5.

Reversing the order alters the final output. For example, scaling before translating causes the translation distance itself to be magnified by the scale factor. Behind the scenes, SVG engines represent each operation as a \(3\times3\) affine transformation matrix, multiplying these matrices together to compute the final mapping for every vertex.