I have this example of what I want to achieve. The second set of rects is where I want to get to.

There are two sets of rects in the link above. The first set is where I currently am, I want to scale svg elements in and out. The centre rect is the start position and the first rect is what happens if the user zooms out and the last rect is what happens when the user zooms in.

I want my rects to remain centred as the scaling happens as is displayed in the second set of rects.

If my starting affine matrix looks like this:

$$\begin{bmatrix}1 & 0 & 0\\0 & 1 & 0\\0 & 0 & 1\end{bmatrix}$$

If I change the scale to:

$$\begin{bmatrix}0.5 & 0 & 0\\0 & 0.5 & 0\\0 & 0 & 1\end{bmatrix}$$

What are my calculations to maintain the centre translation for the $Δx$ and $Δy$ parts of the affine matrix to ensure the elements do not get shifted up to the top left when zooming or scaling out.

The result would be something like this:

$$\begin{bmatrix}0.5 & 0 & -22.5\\0 & 0.5 & -22.5\\0 & 0 & 1\end{bmatrix}$$

The rects have a width of $50$ and a starting point of $(20, 20)$ before each transformation is applied.


2 Answers 2


$\def\vec{\boldsymbol}$For a general setting, suppose the fixed point of this affine transformation is $(x_0, y_0)$, which is the center in your case. Since the scaling matrix is $A = \begin{pmatrix}a&0\\0&b\end{pmatrix}$, then$$ A \begin{pmatrix}x_0\\y_0\end{pmatrix} + \vec{b} = \begin{pmatrix}x_0\\y_0\end{pmatrix} \Longrightarrow \vec{b} = (I - A) \begin{pmatrix}x_0\\y_0\end{pmatrix} = \begin{pmatrix}(1 - a)x_0\\(1 - b)y_0\end{pmatrix}. $$ Therefore, the affine transformation matrix is$$ M = \begin{pmatrix}A & \vec{b}\\\vec{0} & 1\end{pmatrix} = \begin{pmatrix}a & 0 & (1 - a)x_0\\0 & b & (1 - b)y_0\\0 & 0 & 1\end{pmatrix}. $$

  • $\begingroup$ I am afraid this is perhaps a bit above my maths level. I don't understand what $A$ and $b$ are and why is the calculation for $dy$ or $dx$, $(1 - a)x0$ $\endgroup$
    – dagda1
    Oct 17, 2018 at 19:00
  • $\begingroup$ @dagda1 See Wiki $\endgroup$ Oct 18, 2018 at 11:16
  • $\begingroup$ @Alex Francisco, it looks like two different things have equal notation $b.$ $\endgroup$
    – user376343
    Oct 23, 2018 at 9:46
  • $\begingroup$ @user376343 Thanks for pointing out. Corrected now. $\endgroup$ Oct 23, 2018 at 10:07
  • $\begingroup$ @dagda1 I suggest you to do computation with the matrix given by Alex. Take e.g. $a=b=0.5$ and $x_0=y_0=20.$ If this gives what you need, take other value of $a=b.$ If it still works, do not be affraid to accept Alex's answer. $\endgroup$
    – user376343
    Oct 23, 2018 at 10:36

Here is a helpful link that illustrates how different css matrix transforms transform the corners of your rectangle.

Here's my handwritten explanation on how to scale rectangles and center them for any scaling length and rectangle size. (I'm happy to host it on stack exchange, it's just that it doesn't appear as though this website supports .pdf files..)

P.S. if you want to keep your rectangles having a starting point at (20, 20), first draw them with a center of (0, 0), and then after you've scaled and centered them, then translate all of them (using the translate operator) to (20, 20)


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .