# Front end · deeply understand the calculation principle of transform function

When it comes to front-end graphics, it can hardly be avoided   transform   Property.

and   transform   There are five built-in functions in different categories (matrix deformation, translation, scaling, rotation and tilt, and there are nine specific details). Developers are often confused by the combination and transformation of different functions.

When facing the demand for accurate positioning, if   transform   If you don't understand the calculation principle thoroughly, it will lead to lengthy code, increased complexity and rapid decline in readability.

In fact, in the front end   transform   There are many kinds, such as   CSS and   In SVG   transform   Properties are slightly different. However, all changes are inseparable from their religion, and their underlying mathematical principles are generally consistent.

Therefore, for the convenience of description, this article uses   Mainly SVG transform.

First, it can be avoided   There are a lot of different unit conversions in CSS, and many details unrelated to the principle are arranged;
Second, as a vector format   SVG is concise enough to describe the mathematical calculation method, and vectorization parameters have inherent advantages;

## ① transform: matrix(a, b, c, d, e, f)

When it comes to graphics, it must involve matrix operation.

matrix   Function can be said to be the most original existence. If you imagine the front-end page as a canvas, matrix   Is the reformer of this canvas. You only need to set different parameters   matrix   Transform the graphics at will.

At the same time, matrix   Function is also the core of the other four types of function functions. These four types are translation, scaling, rotation and tilt, and their implementation methods can be used   matrix   Equivalent substitution.

matrix   The argument to the function is a   3x3   The length of the explicit parameter list in the function declaration is   6.

The matrix form is as follows (assuming   M):

$$M = \begin{pmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \\ \end{pmatrix}$$

How?

Suppose there is a point on the page   point_old   The coordinates of are   (oldX, oldY), new point after conversion   point_new   Coordinates are   (newX, newY).

During the operation, the matrix description of points is as follows:

$$point_{old} = \begin{pmatrix} oldX \\ oldY \\ 1 \end{pmatrix} \\ point_{new} = \begin{pmatrix} newX \\ newY \\ 1 \end{pmatrix}$$

The calculation method is:

$$point_{new} = M * point_{old}$$

$$\begin{pmatrix} newX \\ newY \\ 1 \\ \end{pmatrix} = \begin{pmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix} = \begin{pmatrix} a*oldX+c*oldY+e \\ b*oldX+d*oldY+f \\ 1 \\ \end{pmatrix}$$

So:

$$point_{new} \begin{cases} newX = a*oldX + c*oldY + e \\ newY = b*oldX + d*oldY + f \\ \end{cases}$$

Among the six parameters, e and f   Mainly responsible for offset, others   a,b,c,d   Represents different magnification.

Now we know that different effects can be achieved by controlling these six parameters.

For example, in the default state, matrix(1, 0, 0, 1, 0, 0)   It means nothing, because applying the above calculation formula,

$$\begin{pmatrix} newX \\ newY \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 1*oldX+0*oldY+0 \\ 0*oldX+1*oldY+0 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix}$$

As a result, it can be found that there is no transformation of point coordinates.

Here, transform   Core function of   matrix()   It should be clear how it is calculated.

Then let's see how all the other functions are implemented and implemented   matrix   Converted.

<h1>default</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9"></rect>
</svg>

## ② transform: translate(x)

translate   It is a translation function. When there is only one parameter, it indicates how far the graph has moved horizontally.
Namely:

$$newX = x + oldX$$

So it's very simple to construct a matrix   matrix(1, 0, 0, 1, x, 0)   Can be achieved   translate(x)   Effect of:

$$\begin{pmatrix} newX \\ newY \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 1 & 0 & x \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 1*oldX+0*oldY+x \\ 0*oldX+1*oldY+0 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} x + oldX\\ oldY \\ 1 \\ \end{pmatrix}$$

<div>
<h1>transform: translate(x)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="translate(100)"></rect>
</svg>

<h1>transform: matrix(1, 0, 0, 1, x, 0)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="matrix(1,0,0,1,100,0)"></rect>
</svg>
</div>

## ③ transform: translate(x, y)

It can be regarded as a single parameter   Overloaded function of translate function, second parameter   y   Value representing y in a two-dimensional plane in Cartesian coordinates   Translational motion in the axis direction.

Namely:

$$\begin{cases} newX = x + oldX \\ newY = y + oldY \end{cases}$$

Similarly, a matrix can be constructed   matrix(1, 0, 0, 1, x, y)   realization   translate(x, y)   Effect of:

$$\begin{pmatrix} newX \\ newY \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 1 & 0 & x \\ 0 & 1 & y \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 1*oldX+0*oldY+x \\ 0*oldX+1*oldY+y \\ 1 \\ \end{pmatrix} = \begin{pmatrix} x + oldX \\ y + oldY \\ 1 \\ \end{pmatrix}$$

<div>
<h1>transform: translate(x, y)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="translate(100,50)"></rect>
</svg>

<h1>transform: matrix(1, 0, 0, 1, x, y)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="matrix(1,0,0,1,100,50)"></rect>
</svg>
</div>

## ④ transform: scale(s)

scale   It is a scaling function. When there is only one parameter, it indicates that the graph is on the horizontal and vertical axes to achieve equal scale magnification and reduction.

Namely:

$$\begin{cases} newX = s*oldX \\ newY = s*oldY \end{cases}$$

Since this is proportional amplification, the transformation matrix can be obtained   matrix(s, 0, 0, s, 0, 0):

$$\begin{pmatrix} newX \\ newY \\ 1 \\ \end{pmatrix}= \begin{pmatrix} s & 0 & 0 \\ 0 & s & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix}= \begin{pmatrix} s*oldX+0*oldY+0 \\ 0*oldX+s*oldY+0 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} s*oldX \\ s*oldY \\ 1 \\ \end{pmatrix}$$

<div>
<h1>transform: scale(s)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="scale(2)"></rect>
</svg>

<h1>transform: matrix(s, 0, 0, s, 0, 0)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="matrix(2,0,0,2,0,0)">
</rect>
</svg>
</div>

## ⑤ transform: scale(sx, sy)

Here, similarly, it is also an overloaded function with two parameters, so that the scaling magnification of different axes can be controlled separately.

Namely:

$$\begin{cases} newX = sx*oldX \\ newY = sy*oldY \end{cases}$$

Similarly, the transformation matrix can be obtained   matrix(sx, 0, 0, sy, 0, 0):

$$\begin{pmatrix} newX \\ newY \\ 1 \\ \end{pmatrix}= \begin{pmatrix} sx & 0 & 0 \\ 0 & sy & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix} = \begin{pmatrix} sx*oldX+0*oldY+0 \\ 0*oldX+sy*oldY+0 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} sx*oldX \\ sy*oldY \\ 1 \\ \end{pmatrix}$$

<div>
<h1>transform: scale(sx, sy)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="scale(0.5,2)"></rect>
</svg>

<h1>transform: matrix(sx, 0, 0, sy, 0, 0)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="matrix(0.5,0,0,2,0,0)"></rect>
</svg>
</div>

## ⑥ transform: rotate(a)

rotate   Is a rotation function, when the number of parameters is   one   When, it indicates that the origin of the current element coordinate system is the rotation point and the rotation angle is   a   Degrees.

It should be noted in advance that the unit here is   deg, angle system.

And then converted into   matrix   Trigonometric functions are needed in the process of.

Therefore, in terms of numerical value, it is necessary to convert the angle system into radian system:

$$a'=\frac{\pi}{180}*a$$

In addition, under the two-dimensional plane rotation motion, the distance from any point to the center of the rotation circle remains unchanged. Therefore, for the convenience of calculation, we use the polar coordinate system to deduce the motion mode of the object in the Cartesian coordinate system.

According to the polar coordinate system, we use ordinal pairs   ( ρ, θ)   Represents any point   P   Coordinates of, ρ  Represents the polar diameter, θ**  Represents the polar angle (radian system).

Record as   P( ρ, θ)

So, any point rotates   a   Angle (a '   The coordinate after radian) is: P( ρ, θ + a')**

Using the mapping relationship between coordinate systems:

$$\begin{cases} X = \rho*cos(\theta) \\ Y = \rho*sin(\theta) \\ \end{cases}$$

Available:

$$newP = oldP(\rho,\theta + a')$$

$$\begin{cases} newX = \rho*cos(\theta+a') \\ newY = \rho*sin(\theta+a') \\ \end{cases}$$

Further expansion can be obtained:

\begin{aligned} newX &= \rho*cos(\theta+a') \\ &= \rho*cos(\theta)*cos(a')-\rho*sin(\theta)*sin(a') \\ &= oldX*cos(a')-oldY*sin(a') \\ &= cos(a')*oldX + (-1)*sin(a')*oldY \\ \end{aligned}

\begin{aligned} newY & = \rho*sin(\theta+a') \\ & = \rho*sin(\theta)*cos(a')+\rho*cos(\theta)*sin(a') \\ & = oldY * cos(a') + oldX * sin(a') \\ & = sin(a') * oldX + cos(a') * oldY \end{aligned}

According to the above formula, it can be deduced that the transformation matrix is   matrix(cos(a'), sin(a'), -sin(a'), cos(a'), 0, 0)

\begin{aligned} \begin{pmatrix} newX \\ newY \\ 1 \\ \end{pmatrix} & = \begin{pmatrix} cos(a') & -sin(a') & 0 \\ sin(a') & cos(a') & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix} \\ & = \begin{pmatrix} cos(a')*oldX-sin(a')*oldY+0 \\ sin(a')*oldX+cos(a')*oldY+0 \\ 1 \\ \end{pmatrix} \\ & = \begin{pmatrix} \rho*cos(a')*cos(\theta)-\rho*sin(a')*sin(\theta) \\ \rho*sin(a')*cos(\theta)+\rho*cos(a')*sin(\theta) \\ 1 \\\end{pmatrix} \\ & = \begin{pmatrix} \rho*cos(\theta + a') \\ \rho*sin(\theta + a') \\ 1 \\ \end{pmatrix} \end{aligned}

<div>
<h1>transform: rotate(a)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="rotate(30)"></rect>
</svg>

<h1>transform: matrix(cos(a'), sin(a'), -sin(a'), cos(a'), 0, 0)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="matrix(0.866025,0.5,-0.5,0.866025,0,0)"></rect>
</svg>
</div>

## ⑦ transform: rotate(a, x, y)

When   rotate   The situation is a little more complicated when the function is specified with a rotation point.

Since the function essentially controls the canvas itself, it can also be understood as the coordinate system itself.

Therefore, if you want a figure in the coordinate system to rotate around a specific point, you need the following three steps:

First, move the rotation point from the origin of the coordinate system to the specified point;
Second, the specified point defaults to the origin of the coordinate system and starts rotation;
Third, in order to keep other patterns unchanged during rotation, move the origin of the coordinate system from the specified point back to the initial point.

Therefore, the rotation of the specified point is usually adopted   < translate(x, y)><rotate(a)><translate(-x, -y)>   The way.

translate   Parameters in   x,y   mean   rotate(a, x, y)   Coordinates of the specified point in the.

In this case, how should we use it   matrix   What about the description?

We assume that the above three transformation matrices are:

$$\begin{cases} translate(x,y)= T_1 = \begin{pmatrix} 1 & 0 & x \\ 0 & 1 & y \\ 0 & 0 & 1 \\ \end{pmatrix} \\ rotate(a) = R = \begin{pmatrix} cos(a') & -sin(a') & 0 \\ sin(a') & cos(a') & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \\ translate(-x,-y)=T_2= \begin{pmatrix} 1 & 0 & -x \\ 0 & 1 & -y \\ 0 & 0 & 1 \\ \end{pmatrix} \end{cases}$$

Then, according to the function execution method, the matrix calculation method is:

$$\begin{pmatrix} newX \\ newY \\ 1 \\ \end{pmatrix} = T_1 * R * T_2 * \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix}$$

Namely:

\begin{aligned} M & = T_1 * R * T_2 \\ & = \begin{pmatrix} 1 & 0 & x \\ 0 & 1 & y \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} cos(a') & -sin(a') & 0 \\ sin(a') & cos(a') & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} 1 & 0 & -x \\ 0 & 1 & -y \\ 0 & 0 & 1 \\ \end{pmatrix} \\ &= \begin{pmatrix} cos(a') & -sin(a') & x \\ sin(a') & cos(a') & y \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} 1 & 0 & -x \\ 0 & 1 & -y \\ 0 & 0 & 1 \\ \end{pmatrix} \\ &= \begin{pmatrix} cos(a') & -sin(a') & -x*cos(a')+y*sin(a')+x \\ sin(a') & cos(a') & -x*sin(a')-y*cos(a')+y \\ 0 & 0 & 1 \end{pmatrix} \end{aligned}

That is, the transformation matrix is:
matrix(cos(a'), sin(a'), -sin(a'), cos(a'), -xcos(a')+ysin(a')+x, -xsin(a')-ycos(a')+y)

$$\begin{pmatrix} newX \\ newY \\ 1 \end{pmatrix} = \begin{pmatrix} cos(a') & -sin(a') & -x*cos(a')+y*sin(a')+x \\ sin(a') & cos(a') & -x*sin(a')-y*cos(a')+y \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix}$$

<div>
<h1>transform: rotate(a, x, y)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="rotate(30,0,100)"></rect>
</svg>

<h1>transform: matrix(cos(a'), sin(a'), -sin(a'), cos(a'), -x*cos(a')+y*sin(a')+x, -x*sin(a')-y*cos(a')+y)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="matrix(0.866025, 0.5, -0.5, 0.866025, 50.0, 13.39746)"></rect>
</svg>
</div>

## ⑧ transform: skewX(a)

skewX means   x   For the inclination in the axis direction, the trigonometric function will also be used here. Similarly, there is the following in radian system:

$$a'=\frac{\pi}{180}*a$$

Because tilting only occurs in   x   Axial direction, from which:

$$\begin{cases} newX = \Delta x + oldX = tan(a')*oldY + oldX\\ newY = oldY \end{cases}$$

Therefore, the transformation function is   matrix(1, 0, tan(a'), 1, 0, 0)

\begin{aligned} \begin{pmatrix} newX \\ newY \\ 1 \\ \end{pmatrix} & = \begin{pmatrix} 1 & tan(a') & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix} \\ & = \begin{pmatrix} 1*oldX+tan(a')*oldY+0 \\ 0*oldX+1*oldY+0 \\ 1 \\ \end{pmatrix}\\ &= \begin{pmatrix} tan(a')*oldY + oldX\\ oldY \\ 1 \\ \end{pmatrix} \end{aligned}

<div>
<h1>transform: skewX(a)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="skewX(30)"></rect>
</svg>

<h1>transform: matrix(1, 0, tan(a'), 1, 0, 0)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="matrix(1,0,0.577350,1,0,0)"></rect>
</svg>
</div>

## ⑨ transform: skewY(a)

skewY indicates the inclination in the y-axis direction. The principle is the same as above:

$$\begin{cases} newX = oldX \\ newY = \Delta y + oldY = tan(a')*oldX + oldY \\ \end{cases}$$

The transformation function matrix(1, tan(a'), 0, 1, 0, 0) can be obtained

\begin{aligned} \begin{pmatrix} newX \\ newY \\ 1 \\ \end{pmatrix} & = \begin{pmatrix} 1 & 0 & 0 \\ tan(a') & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} oldX \\ oldY \\ 1 \\ \end{pmatrix} \\ & = \begin{pmatrix} 1*oldX + 0*oldY + 0 \\ tan(a')*oldX+1*oldY + 0 \\ 1 \\ \end{pmatrix}\\ &= \begin{pmatrix} oldX\\ tan(a')*oldX+oldY \\ 1 \\ \end{pmatrix} \end{aligned}

<div>
<h1>transform: skewY(a)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="skewY(30)"></rect>
</svg>

<h1>transform: matrix(1, tan(a'), 0, 1, 0, 0)</h1>
<svg x="0px" y="0px" width="600px" height="300px">
<line label="axisX" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="600" y2="0" />
<line label="axisY" fill="none" stroke="black" stroke-width="10" x1="0" y1="0" x2="0" y2="300" />
<rect x="0" y="0" width="200" height="100" fill="red" opacity="0.9" transform="matrix(1,0.577350,0,1,0,0)"></rect>
</svg>
</div>

To sum up, it is   transform   The calculation of all functions.

Or it can also be regarded as its matrix operation description.

Of course, the code may be optimized to reduce unnecessary matrix operation, but it is very useful to understand its operation principle and understand the underlying calculation logic.