transform与Matrix矩阵

问题引入

1.

.box1{
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    height: 50px;
    background: black;
    transform: rotate(45deg) translate(300px,300px) ;
}
.box2{
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    height: 50px;
    background:black;
    transform: translate(300px,300px) rotate(45deg) ;
}

图片描述

可以看到通过transform设置的translate和rotate,2个盒子由于先后顺序不同,但是差别却很大。

2.

.test{
  width: 20px;
  height: 140px;
  background-color: salmon;
  position: absolute;
  top: 500px;
  left: 500px;
  transform: rotate(90deg);
  transform: scale(0.5);
}
.test:hover
{
    transform: rotate(45deg);
}

图片描述

hover后:
图片描述

可以看到 hover后transform: rotate(45deg); 使得一开始设置的scale恢复了初始值1。
由此可见,transform 是组件化的,其中的2D图像变化并不只是单纯的skew(),scale(),rotate(),translate()等

Matrix

matrix()

CSS 函数 matrix() 用六个指定的值来指定一个均匀的二维(2D)变换矩阵。这个矩形中的常量值是不作为参数进行传递的,其他的参数则在主要列的顺序中描述。
举个例子

transform: 'translate(tx,ty) rotate(a) skew(b) scale(sx.sy)'

代表将坐标系先 translate 然后 rotate 然后 skew 然后 scale 为新的坐标系。即新坐标系下的点先经过 scale 然后 skew 然后 rotate 然后 translate 后对应于老坐标系下的点。

那Matix是如何运算的呢?

引用文字

在笛卡尔坐标系中,每个 欧氏空间 里的点都由横坐标和纵坐标这两个值来确定。 在CSS(和大部分的计算机图形学)中,原点 (0, 0) 在元素的左上角。每个点都使用数学上的向量符号(x,y)来描述。

每个线性函数使用 2 × 2 矩阵描述,如:

     [a c]
     [b d]

将矩阵乘法用于上述坐标系中的每个点,一个变换就形成了:

可以在一行中进行多次矩阵乘法进行变换:
图片描述

有了这种方法,就可以描述大部分常见的变换并因此可以将他们组合起来,如:旋转、缩放或拉伸。(事实上,所有线性函数的变换都可以被描述。)组合的变换是从右到左生效的。然而,有一种常见的变换并不是线性的,所以当这种变换要用这种方法来表示时,应该被单独列出来:位移。位移的向量 (tx, ty) 必须单独表示,作为两个附加参数。

而上面的例子可以写成

clipboard.png

显而易见的
tranmsform的属性是由Matrix矩阵通过参数计算出来

计算方法

translate(tx,ty)
transform: matrix(1, 0, 0, 1, tx, tx)

这两个是等价的 , 意味着translate的两个参数 ,被transform放到了第五个和第六个参数中计算。

同样的

scale(sx, sy)
matrix(sx, 0, 0, sy, 0, 0)

这两个也是等价的

如果是旋转rotate(),则要用到三角函数

rotate(θ)
matrix(cosθ,sinθ,-sinθ,cosθ,0,0)

skew()则是使用tan()

skew(θ)
matrix(1,tan(θy),tan(θx),1,0,0)

再通过上面的矩阵相乘公式,可以算得Matrix函数参数值

问题1中,可以表达成

    
   [1,0,300]    [cos45°, -sin(45°) ,0]
   [0,1,300] *  [sin45°,  cos45°,    0]
   [0,0, 1 ]    [   0,     0 ,       1]

相反的 矩阵相乘不满足交换律, 当translate(300px,300px)和rotate(45deg)两个顺序互换的话,矩阵相乘算得结果参数不同, 所以对应的效果也会不同

问题2中

原本transform通过rotate和scale用2个矩阵相乘赋予了Matrix()函数参数
然而transform一旦再次设置rotate(),则会将Matrix()函数参数重置,
所以才会使得transform之前设置的属性荡然无存。

结语

原本CSS3的问题, 怎么就不知不觉变成线代问题了呢 - -

157 声望
9 粉丝
0 条评论
推荐阅读
Vue+mint-ui+flexible仿移动端App(网易云课堂)
Vue-wyclass 仿网易云课堂App 在线预览:手机浏览或切换谷歌浏览器移动调试 Gif预览 描述 前端部分 Vue2.0 + Mint-ui快速构建前端界面(轮播图,swiper滑块) ---Mint-ui Vuex 管理现非父子组件之间的通信 移动设...

robin11阅读 10.2k评论 3

还在用 JS 做节流吗?CSS 也可以防止按钮重复点击
举个例子:一个保存按钮,为了避免重复提交或者服务器考虑,往往需要对点击行为做一定的限制,比如只允许每300ms提交一次,这时候我想大部分同学都会到网上直接拷贝一段throttle函数,或者直接引用lodash工具库

XboxYan35阅读 2.6k评论 2

封面图
【关于Javascript】--- 正则表达式篇
基础知识一、元字符 {代码...} 二、量词 {代码...} 三、集合 字符类 {代码...} 四、分支 {代码...} 五、边界 开始结束 {代码...} 六、修饰符 {代码...} 七、贪婪模式和非贪婪模式js默认贪婪模式即最大可能的匹配...

Jerry35阅读 3.1k

CSS transition 小技巧!如何保留 hover 的状态?
欢迎关注我的公众号:前端侦探通常情况下,hover 是无法保存状态的。鼠标移入触发额外样式,一旦移出就还原了 {代码...} 这就意味着,如果需要保留hover的状态,可能就不得不借助JS了,比如下面是某某书院的首页...

XboxYan30阅读 3.9k评论 2

封面图
CSS 如何设置自动滚动定位的“安全”间距?
欢迎关注我的公众号:前端侦探介绍两个和滚动定位相关的 CSS 属性:scroll-padding和 scroll-margin在平时开发中,经常会碰到需要快速定位的问题,比如常见的锚点定位 {代码...} 这样,在点击a标签时会自动定位到...

XboxYan31阅读 2.5k评论 2

封面图
【已结束】SegmentFault 思否写作挑战赛!
SegmentFault 思否写作挑战赛 是思否社区新上线的系列社区活动在 2 月 8 日 正式面向社区所有用户开启;挑战赛中包含多个可供作者选择的热门技术方向,根据挑战难度分为多个等级,快来参与挑战,向更好的自己前进!

SegmentFault思否20阅读 5k评论 10

封面图
由小见大!不规则造型按钮解决方案
今天,有个群友在群里提问,使用 CSS 能否实现下述这个图形:emmm,中间这个酷似三次贝塞尔曲线的造型,使用 CSS 不太好实现。我的建议是切图实现,然而群友要求一定要用 CSS 实现。虽然麻烦,但是这个图形勉强也...

chokcoco17阅读 1.3k

封面图
157 声望
9 粉丝
宣传栏