Skip to content

Instantly share code, notes, and snippets.

@fospathi
Last active August 15, 2022 23:20
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fospathi/0ff9f8bb878b6f9c0945b06b62d54d7a to your computer and use it in GitHub Desktop.
Save fospathi/0ff9f8bb878b6f9c0945b06b62d54d7a to your computer and use it in GitHub Desktop.
SVG matrix to flip the Y-axis direction
The Y-axis in an SVG document points towards the bottom of the page, that is the Y value increases the further down the page
you go. When positioning items in a maths or physics context however it is more appropriate to have the Y-axis pointing up
the page like a normal coordinate system. We can provide an affine transformation matrix to a g element's transform
attribute that flips the Y-axis for its children.
Let the value of the viewBox attribute of the document's SVG element equal "0 0 w h". Suppose we want a coordinate system
whose origin is at the centre of the viewbox and whose Y-axis points up to the top of the page.
(0, 0)
O_ _ _ _ _ _ _ _\ X (Default SVG coordinate system/frame)
| /
|
|
| /|\ Y
| |
| |
| |
Y \|/ | _ _ _ _ _ _\ X (New coordinate system/frame)
O /
(w/2, h/2)
We require a transformation that transforms coordinates in the new coordinate system frame back to coordinates in the SVG
default standard frame. This change of frame transformation matrix, M, has six unknowns
M = | a c e | Note that this is a shorthand version of an affine transformation matrix M = | a c e |
| b d f | | b d f |
| 0 0 1 |
The first column's unknowns are the components of the unit vector describing the new X-axis direction, so (1, 0) in this
case. The second column's unknowns are the components of the unit vector describing the new Y-axis direction, so (0, -1)
in this case. The third column's unknowns are the coordinates of the new origin, so (w/2, h/2) in this case.
M = | 1 0 w/2 |
| 0 -1 h/2 |
The SVG transform attribute accepts matrices given in the form matrix(a b c d e f), so in this case the correct form is
matrix(1 0 0 -1 w/2 h/2).
Consider as an example a square viewbox of length 10, that is w = h = 10.
<!-- An SVG document -->
<!-- The height and preserveAspectRatio attributes are provided here just for completeness -->
<!-- The main attributes to note are the viewBox and transform attributes on the svg and g elements respectively -->
<svg viewBox="0 0 10 10" preserveAspectRatio="xMidYMid slice" height="100%">
<g transform="matrix(1 0 0 -1 5 5)">
<!-- The child elements of this g element can use normal math style coordinates -->
<!-- The origin is at the viewBox centre, the X-axis domain is -5 to 5 and the Y-axis range is -5 to 5 -->
...
</g>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment