transform 属性之 matrix 方法其二

本文为解析 transform 属性系列的第三篇,未看前文的童鞋,阅读一下 第一篇第二篇,会对本文有更好的理解。

matrix 矩阵运算公式

x’ = a * x + c * y + tx
y’ = b * x + d * y + ty

详细运算过程请参考上一篇文章

matrix 实现 rotate

回顾一下 rotate 的定义:

rotate(degree)
rotate 方法用于将元素旋转一定的角度。当 degree 的值为正数时,顺时针旋转元素;为负值时,逆时针旋转元素。


旋转元素,可以想象将元素分为好多分散的点,把元素中包含的每一个点绕着元素中心旋转。单个点的操作就类似于下图中的 A 点旋转一定角度后变为了 B 点,将旋转后所有点组合,就是旋转后的元素了。
rotate-point
由上图可见,给最初的角度 α 增加旋转角度 θ,A 点就由之前的位置变换到了 B 点。由此可以得出这样的信息:

  • 点 A 是已知的
  • 变换前后,线段 OA 和 OB 是相等的
  • 旋转角度 θ 也是已知的
  • 点 B 是未知点

将问题抽象出来,即:已知圆上的点 A,求将点 A 旋转角度 θ 后新位置点 B 的坐标?

有一个经典的坐标系统可以用来处理上面这个问题,它就是极坐标系(极坐标系的详细介绍请咨询度娘)。将以上问题用极坐标系表示如下图:
polar-coordinate
由上图得知:
A 点在直角坐标系与极坐标系的坐标转换关系为,

x = r * cos(ɑ)
y = r * sin(ɑ)

B 点在直角坐标系与极坐标系的坐标转换关系为,

x’ = r * cos(ɑ + θ)
y’ = r * sin(ɑ + θ)

注意此处, x 与 y 是上面问题已知数, θ 是上面问题的已知角度。

故:

x' = r * cos(ɑ + θ) = r * (cosɑ * cosθ - sinɑ * sinθ)
                    = r * cosɑ * cosθ - r * sinɑ * sinθ
                    = x * cosθ - y * sinθ

y' = r * sin(ɑ + θ) = r * (sinɑ * cosθ + cosɑ * sinθ)
                    = r * sinɑ * cosθ + r * cosɑ * sinθ
                    = y * cosθ + x * sinθ

Ps:三角函数相关运算不明白的话请咨询度娘。

结合矩阵运算公式,可以很容易的得到以下结论:

当 a 为 cosθ,c 为 -sinθ,b 为 sinθ,d 为 cosθ,且 tx 与 ty 均为 0 时,matrix 方法的功能就和 rotate 一样。即:

                         x' = a * x + c * y + tx
                         y' = b * x + d * y + ty
                                        ↓
                        x' = cosθ * x - sinθ * y
                        y' = sinθ * x + cosθ * y

了解了理论依据,下面用 matrix 来实现 rotate 的旋转效果:
代码如下:

.matrix-style-rotate {
   /* transform: rotate(30deg); */
   transform: matrix(0.866025, 0.5, -0.5, 0.866025, 0, 0);
}

效果如下:
matrix-rotate

matrix 实现 skew

回顾一下 skew 的定义:

skew(xDegree, yDegree)
skew 方法用于将元素倾斜一定的角度。xDegree 代表沿水平方向(X轴)倾斜的角度,yDegree 代表沿竖直方向(Y轴)倾斜的角度。


相比于旋转效果而言,倾斜更好理解一些。与旋转不同的是,倾斜元素会改变元素的大小。

沿水平方向倾斜元素,可以想象将元素分为好多条竖直线,然后将每一条竖直线倾斜,最后再组合在一起,即为倾斜后的元素。而单条竖直线的倾斜类似于下图红色矩形中线段BO到蓝色矩形中线段BA的效果。
skew-horizontal
如图,将红色矩形向右倾斜角度 θ,就可以得到蓝色矩形。

将问题抽象出来,即:已知线段 BO 和倾斜角度 θ,求在水平方向倾斜后的点 A?

由三角函数公式,很容易得知上图中 OA 长度为 tanθ * BO。如问题所示,B 点的坐标已知为 (x, y),那么图中 A 点水平方向的坐标即为 tanθ * y。而相对于原始倾斜点来说,变换后水平方向坐标即为 x + tanθ * y。

同样的,沿竖直方向倾斜元素,可以想象将元素分为好多条水平线,然后将每一条水平线倾斜,最后再组合在一起,即为倾斜后的元素。而单条水平线的倾斜类似于下图红色矩形中线段BO到蓝色矩形中线段BA的效果。
skew-vertical
如图,将红色矩形向下倾斜角度 θ,就可以得到蓝色矩形。

将问题抽象出来,即:已知线段 BO 和倾斜角度 θ,求在竖直方向倾斜后的点 A?

由三角函数公式,很容易得知上图中 OA 长度为 tanθ * BO。如问题所示, B 点的坐标已知为 (x, y),那么图中 A 点竖直方向的坐标即为 tanθ * x。而相对于原始倾斜点来说,变换后竖直方向坐标即为 y + tanθ * x。

结合矩阵运算公式,可以很容易的得到以下结论:

当 a 为 1,c 为沿水平方向倾斜角度 θ 的正切值,b 为 1,d 为沿竖直方向倾斜角度 θ’ 的正切值,且 tx 和 ty 均为 0 时,matrix 方法的功能就和 skew 方法一样。即:

                         x' = a * x + c * y + tx
                         y' = b * x + d * y + ty
                                        ↓
                            x' = x + tanθ * y
                            y' = tanθ' * x + y

请注意此处 θ 和 θ’ 分别代表沿水平方向倾斜角度和沿竖直方向倾斜角度,它们可以相等也可以不相等。

明确了转换关系后,就可以用 matrix 来实现 skew 的倾斜效果:
代码如下:

.matrix-style-skew {
   /* transform: skew(30deg, 30deg); */
   transform: matrix(1, 0.577350, 0.577350, 1, 0, 0);
}

效果如下:
matrix-skew

未完待续?

本文旨在解析方法执行之根本,知其然且知其所以然,应为我辈之追求。未完待续否?余下精彩,期待你来开发!


更多 CSS 技巧,请关注微信公众号
CSS skill

猜你喜欢

转载自blog.csdn.net/u011848617/article/details/78933660