Логотип Workflow

Article

Transforms Coordinate Systems

Transforms & Coordinate Systems

In SVG, everything is in a coordinate system. By default, the point (0,0) is the upper left corner. The X-axis goes to the right, the Y-axis goes down.

But the most interesting part begins when we want to change the position, size, or slope of objects without changing their initial coordinates (x, y, cx, cy), but by changing the space around them. For this, the transform attribute is used.


1. The transform attribute

This attribute works similarly to the CSS transform property, but is applied directly to SVG tags. You can list one or more functions in a row inside the attribute.

translate(tx, ty) - Move

Shifts the object's coordinate system.

  • tx - shift along the X-axis.
  • ty - shift along the Y-axis (optional, if not specified, it is considered 0).
<svg width="200" height="100" viewBox="0 0 200 100">
  <!-- Original square (semi-transparent) -->
  <rect x="0" y="0" width="40" height="40" fill="crimson"/>
</svg>
<svg width="200" height="100" viewBox="0 0 200 100">
  <!-- Shifted square -->
  <rect x="0" y="0" width="40" height="40" fill="crimson" 
        transform="translate(50, 20)" />
</svg>

rotate(angle) - Rotation

Rotates the object by the specified number of degrees clockwise.

  • angle - angle in degrees (45, -90, etc.).

scale(sx, sy) - Scaling

Enlarges or reduces an object.

  • sx - multiplier for X.
  • sy - multiplier for Y (if not specified, it is equal to sx).

Important nuance: scale scales everything, including coordinates and stroke thickness. If you increase a circle by 2 times (scale(2)), its stroke stroke-width="1" will visually turn into 2.


skewX(angle) and skewY(angle) - Skew

Distorts an object along the axes.


2. The problem of transform-origin (Point of rotation)

This is the most common pain for beginners in SVG.

  • In CSS (HTML): If you rotate a <div>, it rotates around its center.
  • In SVG (by default): Objects rotate around the point (0,0) of the entire canvas (the upper left corner of the SVG).

If your square is at coordinates x="100", and you write rotate(45), it will not just turn, it will "fly" in an arc around the origin.

How to fix it?

Method 1: Old SVG style (in the attribute)

The rotate function in SVG takes optional 2nd and 3rd parameters: the coordinates of the center of rotation rotate(angle, cx, cy).

<!-- Rotate a 50x50 square around its center (25, 25) -->
<rect x="0" y="0" width="50" height="50" transform="rotate(45, 25, 25)" />

Method 2: Modern CSS (Recommended)

If you are styling SVG via CSS, use the transform-box property. It tells the browser: "consider the object itself as the center, not the entire SVG".

.my-element {
  /* Specify that the origin is calculated relative to the boundaries of the object itself */
  transform-box: fill-box;
  /* Now the center works as expected */
  transform-origin: center;
  transform: rotate(45deg);
}

3. Nested coordinate systems

When you apply a transformation to a <g> group, magic happens. You are not transforming the objects inside, but the coordinate grid for this group itself.

Imagine a sheet of graph paper:

  1. You draw a square on it.
  2. You rotate the sheet of paper itself by 45 degrees.
  3. Now, if you ask to draw another square and move it "to the right" (translate(10, 0)), it will visually move diagonally, because the X-axis on this sheet now looks diagonally.
<svg width="300" height="200" viewBox="0 0 300 200">
  <!-- The group is shifted and rotated -->
  <g transform="translate(100, 50) rotate(45)">
    
    <!-- The square is drawn at point 0,0 INSIDE the group. 
         But visually it will be in the center of the canvas and rotated. -->
    <rect x="0" y="0" width="50" height="50" fill="purple" />
    
    <!-- The text also obeys the rules of the group -->
    <text x="0" y="70">I'm also rotated!</text>
  </g>
</svg>

Order matters!

  • transform="translate(50, 0) rotate(45)" - First move to the right, then rotate there.
  • transform="rotate(45) translate(50, 0)" - First rotate the coordinate system, then move along the already rotated X-axis (that is, diagonally).

Summary

  • translate moves, rotate rotates, scale changes size (along with line thickness!).
  • By default, rotation occurs around (0,0) (the upper left corner of the SVG), and not around the center of the figure.
  • To rotate around the center, use CSS: transform-box: fill-box; transform-origin: center; or arguments in the rotate(deg, cx, cy) attribute.
  • Transformations of <g> groups affect all children, creating nested ("local") coordinate systems.

Quiz

Check what you learned

Please login to pass quizzes.