Transform的值大类

transform 本质上来说是一系列的变形函数,主要有以下值:
none - 不进行转换,常用作覆盖别的值使用
translate(x,y) - 2d位移;translate3d(x,y,z) - 3d位移; transformX/Y/Z(n) - 单向位移
scale(x,y) - 2d缩放; scale3d(x,y,z) - 3d缩放; scaleX/Y(n) - 单向缩放
rotate(angle) - 2d旋转; rotate3d(x,y,z,angle) - 3d旋转;rotateX/Y/Z(angle) - 单向旋转
skew(x-angle,y-angle) - 倾斜变换; skewX/Y(angle) - 单向倾斜变换
matrix[3d] - 矩阵
perspective(n) - 视距(值)

Transform的前置属性

transform-origin - 变换原点
transform-style - 变换类型
perspective - 3d透视视图的视距(属性)
perspective-origin - 视距的基点
backface-visibility - 是否可以看见背面

Transform特性

1、如果是动画效果,translate能达到比1px更小的过渡效果,而position却不行,这就影响了用户体验。
2、translate的动画效果能启用电脑GPU加速,分离图层,大大减少页面重绘模块,节省资源。
3、position 的可拓展性不如 translate等。
4、transform百分比的基准是被设置值的本身容器,而不是像margin等以父级为基准。
5、3d效果需要使用在父级使用perspective,否则设置的值无效。

矩阵 - matrix

线性代数里矩阵

1
2
3
4
5
6
7
8
9
|1 0 0|
|1 0 0|
|2 0 0|

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

|a b c|
|d e f|
|0 0 1|

当我们要做变换时,实质上就是对初始值添加一些系数,也就是:

1
2
3
|a c e|   |x|    |ax cy e|
|b d f| * |y| = |bx dy f|
|0 0 1| |1| |0 0 1|

而变化后的x与y坐标

1
2
x' = ax + cy +  e   // 即:x坐标
y' = bx + dy + f // 即:y坐标

默认值:

1
2
matrix(1, 0, 0, 1, 0, 0)
// 在默认基础上继续变化

平移

1
2
3
4
5
6

matrix(a,b,c,d,e,f);
// 只需要变换e,f即可,e为x,f为y
// 如
transform: matrix(1, 0, 0, 1, 10, 20);
// x为10px,y为20px

缩放

1
2
3
4
5
matrix(a,b,c,d,e,f);
// 只需要变换a,d即可,a为x,d为y,既放大缩小多少倍,如果在是正常倍数,设置为1即可,否则图形会消失,如设置为0了
// 如
transform: matrix(2, 0, 0, 2, 0, 0);
// x为2倍,y为2倍

旋转

由于旋转需要使用到三角函数,cos与sin,而且matrix(a,b,c,d,e,f)中要使用都abcd。

1
2
3
4
'matrix('+Math.cos(x)+', '+Math.sin(x)+', -'+Math.sin(x)+', '+Math.cos(x)+', 0, 0)'

// 三角函数的转换
let x = 2 * Math.PI / 360 * angle;

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

<template>
<div class="hello">
<button @click='btnFn'>开始</button>
<div class="wrapper">
<div ref="item" class="item"></div>
</div>
</div>
</template>

<script>
export default {
name: 'HelloWorld',
data () {
return {
timer: null
}
},
mounted(){

},
methods: {
transFn(angle = 0){
let item = this.$refs.item;
let x = 2 * Math.PI / 360 * angle;
item.style.transform = 'matrix('+Math.cos(x)+', '+Math.sin(x)+', -'+Math.sin(x)+', '+Math.cos(x)+', 0, 0)';
},
move(start, end){
clearInterval(this.timer);
this.timer = setInterval(()=>{
this.transFn(start);
if(start >= end){
clearInterval(this.timer);
}else{
start+= 2;
}
}, 100);
},
btnFn(){
this.move(0, 360);
}
}
}
</script>
<style scoped>
.wrapper {
position: absolute;
top: 50%;
left: 50%;
width: 500px;
height: 500px;
perspective: 100px;
}
.item {
background-color: #42b983;
width: 100px;
height: 100px;
transform: matrix(2, 0, 0, 2, 0, 0);
transform-origin: 0 0 0;
}
</style>

拉伸

由于旋转需要使用到三角函数,tan,而且matrix(a,b,c,d,e,f)中要使用都bc。

1
2
3
4
5
6
matrix(1,tan(θy),tan(θx),1,0,0)
// 三角函数的转换
let x = 2 * Math.PI / 360 * angle;
let θ = Math.tan(x);
// 30度
transform: matrix(1, 0.5, 0.5, 1, 0, 0);

以上是对单种变换的matrix使用,若要多个一起使用就要按顺序使用上述的方法累加起来,所以在使用transform是变换使用都会根据使用的变换顺序不同而达到的结果不一样,因为它会根据前一个变换后的结果进行下一次的变换,如

1
2
3
transform: rotate(30deg) translate(10px, 20px);

transform: translate(10px, 20px) rotate(30deg);

以上的数值都一致,但结果是不一样的。
第一个为旋转后根据旋转的方向进行移动
第二个为移动后再进行旋转

matrix 工具