I really need to understand how skew(xdeg)
function works all research does not seem to explain how the x angle affecting the other points and distorts it like that, I need to know if there any mathematical formula it or a way to be able to expect the result of using a specific degree.
ps. I already read tons of docs which the best one of them was the DevDocs which say
This transformation is a shear mapping (transvection) that distorts each point within an element by a certain angle in the horizontal and vertical directions. The coordinates of each point are modified by a value proportionate to the specified angle and the distance to the origin; thus, the farther from the origin a point is, the greater will be the value added it.
but there is no further explanation for how the given angle will affect those points in an element.
In SVG book it explains skew by saying it pushes a horizontal or a vertical line by specific value but I don't get how deg
value is translated to offset one
Description. Returns the skewness of a distribution. Skewness characterizes the degree of asymmetry of a distribution around its mean. Positive skewness indicates a distribution with an asymmetric tail extending toward more positive values.
In statistics, skewness is a measure of the asymmetry of the probability distribution of a random variable about its mean. In other words, skewness tells you the amount and direction of skew (departure from horizontal symmetry). The skewness value can be positive or negative, or even undefined.
SKEW is a function in Excel that calculates the standard deviation of the logarithms of the individual values in a data set. It is most often used to measure the asymmetry of a distribution. The SKEW function can be used in conjunction with the Excel AVERAGE function to calculate the value of the skewness coefficient.
The mathematical operation that is applied on the <angle>
is simply tan(<angle>)
. It is then inserted in the transformation Matrix.
Ok, that doesn't really goes in depth about skew
, nor why it makes sense to use angle rather than a numeric factor. So let's take the following ASCII example showing an x only skew.
skewX(0) skewX(45deg)
_| |_ _| |_ => original box markers
a o o o o a o o o o
b o o o o b o o o o
c o x o o c o x o o <-- this line didn't move
d o o o o d o o o o
e o o o z e o o o z
| | | |
So if we apply the tan(45deg)
it gives us a skewX factor of 1.
This means that all the horizontal lines will get displaced by 1 * their distance to the transformation origin.
In above example the transformation origin is the center (x
) of the 5*5 image.
So the first pixel line (a o o o o
) being at a distance of minus two pixels from the origin, it will get translated by 2px on the left.
The last line (e o o o z
) being at +2px from the origin, it will get translated by 2px on the right.
The middle line (c o x o o
) being on the origin will not be affected by this transform.
Alright, but that still doesn't explain why bother with angles rather than a factor...
Well the angle notation makes sense too, since we could also explain our example as we rotated every column by 45deg using their center point as anchor.
And even if it is just speculations from my part, angles have the added benefit to allow a skewN(90deg)
state which couldn't be represented by a numeric factor.
To understand how skew
works let's compare it with another transformation that uses angle.
Here is an example with rotation, we make the transform origin to be top left
and from there we rotate by 45deg
:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:rgba(255,0,0,0.5);
transform-origin:top left;
transform:rotate(45deg);
}
<div class="box">
<div></div>
</div>
For this example, it's somehow trivial to find the angle and how it works:
Now let's take the same example and reduce the height of the rotated element to a small value:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:3px;
width:100%;
background:red;
transform-origin:top left;
transform:rotate(45deg);
}
<div class="box">
<div></div>
</div>
It's like we have a rotated line. Now let's replace rotate with skew:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:3px;
width:100%;
background:red;
transform-origin:top left;
transform:skewY(45deg);
}
<div class="box">
<div></div>
</div>
If we compare both result we will notice that we have somehow a rotation in both cases BUT a different size when it comes to skew transformation:
It's more clear now how skew works with angle. The transform is a kind of distortion that rely on an angle to define this distortion. Here is a better illustration:
The blue is our initial element, the cross is the transform origin and the yellow is the angle. If we do a rotation we will obtain the red line where the width remain the same. If we do a skew we will obtain the orange line where the width will change and considering the illustration it will be equal to W / cos(angle)
Where W
is our initial width (in our previous case cos(45deg) = 1 / sqrt(2)
so we will have W * sqrt(2)
).
Now what about our intial square, how it will behave with skew?
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform-origin:top left;
transform:skewY(45deg);
}
<div class="box">
<div></div>
</div>
It will behave exactly like we described previously line by line. We will also have the same result if we apply skew in the other direction:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform-origin:top left;
transform:skewX(45deg);
}
<div class="box">
<div></div>
</div>
The same logic is applied but to vertical lines and considering the height. As a side note, skewX(V)
is the same as skew(V)
ref.
Now if we apply skew in both direction:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform-origin:top left;
transform:skew(45deg,10deg);
}
<div class="box">
<div></div>
</div>
It's like we first apply skewX
to distort the vertical lines then we apply skewY
to the new shape to distort the horizontal lines (or the opposite). Here is an animation to illustrate the magic result of skew(45deg,45deg)
:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform-origin:top left;
transform:skew(45deg,10deg);
animation:change 5s infinite alternate linear;
}
@keyframes change {
from {
transform:skew(0deg,0deg);
}
50% {
transform:skew(45deg,0deg);
}
to {
transform:skew(45deg,45deg);
}
}
<div class="box">
<div></div>
</div>
And what about origin? Nothing will change for the transformation, only the reference will change. In other words, the fixed point will move:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform-origin:center;
transform:skew(45deg,10deg);
animation:change 5s infinite alternate linear;
}
@keyframes change {
from {
transform:skew(0deg,0deg);
}
50% {
transform:skew(45deg,0deg);
}
to {
transform:skew(45deg,45deg);
}
}
<div class="box">
<div></div>
</div>
We may also notice that if we do skew in one direction only one parameter of transform-origin
will be considered.
So for skewX
, transform-origin: X Y
will be the same whataver the value of X
is. This somehow explain the line by line transformation as when we have on line we have one dimension.
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform:skewX(45deg);
animation:change 5s infinite alternate linear;
}
@keyframes change {
from {
transform-origin:0 0;
}
50% {
transform-origin:100% 0;/*nothing will happen between 0 and 50%*/
}
to {
transform-origin:100% 100%;
}
}
<div class="box">
<div></div>
</div>
More in depth
Now let's consider the matrix calculation to understand how it's used and how tan(angle)
is also used.
If we refer to the documentation we have:
This matrix is used to define the coordinates of the transformed element based on the coordinate of the initial element point by point. Considering this definition we will have these equations
Xf = Xi + Yi * tan(ax)
Yf = Xi * tan(ay) + Yi
If we consider skewY
only it's clear that ax
will be 0
thus tan(0)
will be 0
and X
won't change which is the case with our first example where we only had distortion in the Y axis (same logic if we apply only skewY).
Now, why we have Yf = Xi * tan(ay) + Yi
?
Let's re-take the previous illustration:
The green point is the initial point defined by Xi,Yi
and the red point is the tranformed one defined by Xf,Yf
. It's trivial that Xf=Xi
and the distance between the two points will be Yf-Yi
.
Considering the illustration we can clearly say that tan(ay) = (Yf-Yi)/Xi = (Yf-Yi)/Xf
thus we will have:
Xf = Xi
Yf = Xi * tan(ay) + Yi
We apply the same logic if we have skew in the other direction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With