1.首先回顾transform属性的相关知识
先理解网页上的x,y轴
transform属性
1.偏移
- transform: translate(x,y) :移动元素位置,x,y为水平和竖直移动的距离,单位是px
- translateX(x) 定义转换,只是用 X 轴的值。 测试
- translateY(y) 定义转换,只是用 Y 轴的值。 测试
- translateZ(z)
2.旋转
- transform: rotate(x deg):2D旋转x度,正值顺时针转,负值逆
- 3D旋转
- rotateX()
- rotateY()
- rotateZ()
- 默认旋转的基点是元素中心点
3.倾斜
- transform: skew(x deg,y deg):2D倾斜,x,y为沿x,y轴倾斜的角度
- skewX()
- skewY()
- skew默认旋转的基点是中心点
- 当倾斜的角度大于45度时,实际看到的元素是反过来的,无论怎么倾斜,元素在x,y轴的投影与原始宽高一致,所以元素才会变形
skew(60deg,60deg) 黄框为原始大小
4.缩放
- transform: scale(x,y) :2D缩放,加参数z可3D缩放,x,y,z数值为缩放倍率如1.5
- scaleX(x) 通过设置 X 轴的值来定义缩放
- scaleY(y) 通过设置 Y 轴的值来定义缩放
- scaleZ(z)
transform-origin属性
设置旋转的基点
-
transform-origin: x-axis y-axis z-axis;
-
x值可以是left/right,center,%,具体px
-
y值可以是top/bottom,center,%,具体px
-
z值自然为z轴的具体坐标
2. transform属性的matrix()
第一次见到这个矩阵,是在用jq获取transform属性的返回值时发现,返回的是一段奇怪的参数,后来多方查阅后才了解,matrix()矩阵表示了transform属性的原理,也就是元素发生变化的原理实现
写法如下:
transform: matrix(a,b,c,d,e,f);
a,b,c,d,e,f的六个参数实际上对应的是一个矩阵
而如果要使元素的坐标变化,其中是实现原理如下:
x,y是元素的原坐标,ax+cy+e对应的是变换后的x轴坐标 x’ ,bx+dy+f对应的是变换后的y轴坐标 y’
- 偏移(translate)
显然,在a,b,c,d值不改变的情况下,改变e,f的值就是改变 x’ ,
y’ 的常数项
所以,若只改变e,f的值,就相当于改变元素的偏移,(e,f)其实就是元素的中心点位置坐标
实际上也就是
transform: matrix(a, b, c, d, e, f);
相当于
transform: translate(e px, f px);
- 缩放(scale)
再观察矩阵的式子,缩放就是改变x,y的系数的倍数
显然,若改变x系数倍数而不改变y系数,则只改变a的值
同理,改变y则需只改变d的值
所以
transform: matrix(a, 0, 0, d, 0, 0);
相当于
transform: scale(a, d);
- 旋转(rotate)
旋转相对复杂些,涉及到三角函数的变换,与a,b,c,d参数有关
transform: matrix(cosθ,sinθ,-sinθ,cosθ,0,0)
矩阵变换实际长这样
所以
transform: matrix(cosθ,sinθ,-sinθ,cosθ,0,0)
相当于
transform: transform:rotate(θ化为弧度制 deg);
若需要获取元素的rotate(θ)的旋转角度θ,则需要利用返回值中的参数值cosθ与sinθ
问题也就转化为:已知sinθ和cosθ,求θ值。这里就需要用到反三角函数了,是个数学问题。
- 倾斜(skew)
倾斜也涉及三角函数,不过只改变的是tanθ的值,只与b,c参数有关,方法如下:
transform: matrix(1,tan(θy),tan(θx),1,0,0)
利用矩阵运算后的结果:
x’ = x+ytan(θx)+0 = x+ytan(θx)
y’ = xtan(θy)+y+0 = xtan(θy)+y
所以
transform: matrix(cosθ,sinθ,-sinθ,cosθ,0,0)
相当于
transform: rotate(θ化为弧度制deg);
- matrix()的优点
相比translate、scale、rotate、skew,matrix()可以实现镜像对称,其实原理就是相对于y=tanθ x直线进行翻转,下面是具体方法(k=θ)
transform: matrix((1-k*k) / (1+k*k), 2k / (1 + k*k), 2k / (1 + k*k), (k*k - 1) / (1+k*k), 0, 0)