您的位置:首页 > Web前端 > CSS

CSS3属性之transform 矩阵转换深入讨论(2D)

2017-02-26 06:44 1061 查看

一、何为矩阵

矩阵如同现实中的方阵,只不过,方阵中的是人,矩阵中的是数值。现实中的方阵:而矩阵则是:所谓矩阵的计算,就是相当于两个方阵的较量。

CSS3中的矩阵

CSS3中的矩阵指的就是一种算法,书写为matrix()和matrix3d(),前者是元素2D平面的移动变换,后者是元素3D变换。2D变换矩阵是3*3,如同上图一样,3D变换矩阵则是4*4的矩阵。熟悉transform属性的都知道,transform有以下的属性方法:
.div { transform: translate(20px,30px);}
.div { transform: rotate(60deg);}
.div { transform: skew(35deg);}
.div { transform: scale(1,0.4);}
分别为translate(偏移)、rotate(旋转)、skew(拉伸)、scale(缩放)等属性方法。那有没有想过,为什么transform: rotate(60deg);  会让元素旋转60度呢?它后面运行的机制是什么?我们可以理解为:无论是旋转还是拉伸什么的,都是通过matrix()实现的(通过改变固定的值),只是类似于transform: rotate(60deg); 这种表现形式,人们更容易理解,方便记忆而已。也是就是说,理解transform中的matrix()矩阵方法,更能让人深入理解css3中的transform属性。

二、transform与坐标系统

通过transform旋转的人可以发现,其默认是绕着中心点旋转的,也就是transform-origin对应的点,也是所有矩阵计算的一个重要依据。

transform-origin属性

transform-origin属性设置元素的偏移中心坐标。元素默认的中心坐标是元素的中间位置。当我们通过transform-origin属性进行设置的,矩阵的相关计算也随之改变,表现出来的效果就是 旋转拉伸中心点的改变。例如:我们设置以右下角为中心点,那么图片基于右下角缩放:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>2D/3D转换属性</title>
<style>

#pho {
width: 410px;
height: 220px;
border: 1px solid red;
}
#pho img {
width: 410px;
height: 220px;
-webkit-transform-origin: right bottom ; /* 坐标中心为右下角 */
-webkit-transform: scale(0.5); /* 基于右下角缩放 */
}

</style>
</head>
<body>

<div id="pho">
<img src="pho.jpg" alt="pho">
</div>

</body>
</html>
效果如下:再举一个例子:我们设置
-webkit-transform-origin: 50px 70px ; /* 以像素50px 70px 为中心点 */
效果如下:此时中心点(0,0)的位置,距离左边50像素,距离顶部70像素,(30,30)后面会用到。

三、matrix()

CSS3中transform的matrix()方法写法如下:
transform: matrix(a,b,c,d,e,f);
其6个参数对应的矩阵是:注:写法是竖着的。坐标变换的公式为:其中,x,y表示转换元素的所有坐标(变量),那么后面的ax + cy + e是怎么来的呢?很简单,根据矩阵算法:3*3矩阵中第一行的第1个值与后面1*3的第1个值相乘,第2个值与第2个相乘,第3个与第3个,然后相加,如下图同色标注:ax + cy + e为变换后的水平坐标,bx + dy + f为变换后的垂直坐标。在进行变换时,需要设置矩阵参数设置矩阵参数:默认矩阵参数matrix(1,0,0,1,0,0)
transform: matrix(1,0,0,1,30,30); /* a = 1, b =0, c = 0,d =1, e = 30, f = 30 */
现在根据矩阵的中心点,假设为(0,0),即x = 0,y = 0。变换后的水平坐标 x 是ax + cy + e = 1*0 + 0*0 + 30 = 30,变换后的垂直坐标 y 是bx + dy +f = 0*0 + 1*0 + 30 = 30。于是,中心坐标由(0,0)变成了(30,30),对照上面的白点(30,30)可以发现,原来(0,0)的位置移动到了(30,30)的位置,是不是向右下偏移了30像素呢。其实,transform: matrix(1,0,0,1,30,30)就等同于transform: translate(30px,30px),注意:偏移、旋转都需要单位的,而matrix()方法不需要单位。下面举个实用的例子更好地理解matirx()方法:用translate()方法将图片向右、向下移动30像素的距离:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>2D/3D转换属性</title>
<style>

#pho {
width: 410px;
height: 220px;
border: 1px solid red;
}
#pho img {
width: 410px;
height: 220px;
-webkit-transform: translate(30px,30px);
-o-transform: translate(30px,30px);
-moz-transform: translate(30px,30px);
-mos-transform: translate(30px,30px);
transform: translate(30px,30px);
}

</style>
</head>
<body>

<div id="pho">
<img src="pho.jpg" alt="pho">
</div>

</body>
</html>
效果如下:用matrix()方法将图片向右、向下移动30像素:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>2D/3D转换属性</title>
<style>

#pho {
width: 410px;
height: 220px;
border: 1px solid red;
}
#pho img {
width: 410px;
height: 220px;
-webkit-transform: matrix(1,0,0,1,30,30);
-o-transform: matrix(1,0,0,1,30,30);
-moz-transform: matrix(1,0,0,1,30,30);
-mos-transform: matrix(1,0,0,1,30,30);
transform: matrix(1,0,0,1,30,30);
}

</style>
</head>
<body>

<div id="pho">
<img src="pho.jpg" alt="pho">
</div>

</body>
</html>
效果如下:我们可以看出,这两种方法的效果一样。那么我们可以得出结论:
transform: matrix(前面,四个,与我,无关,水平偏移距离,垂直偏移距离);
translate方法只与matrix()方法的e,f参数有关。即:translate(e,f)

四、matrix与缩放、拉伸和旋转

scale(缩放)

前面提到,偏移只与matrix()方法的e,f参数有关,那么缩放与哪几个参数有关呢?通过前面
transform: matrix(1,0,0,1,30,30);
发现,偏移与e,f参数有关,元素比例与原来一样,可以发现缩放其实与a,d参数有关,其中,a是缩放x轴,d是缩放y轴。假设缩放比例是m,则有 matrix(m,0,0,m,0,0),  根据公式,就有:x' = ax + cy + e = m*x + 0*y + 0 = m*x;y' = bx + dy + f = 0*x + m*y + 0 = m*y;也就是说,matrix(mx,0,0,my,0,0)就相当于scale(mx,my)。       举例:在水平方向上缩放比例为1,在垂直方向上缩放比例为0.5:
#pho img {
width: 410px;
height: 220px;

-webkit-transform: scale(1,0.5);
-o-transform: scale(1,0.5);
-moz-transform: scale(1,0.5);
-mos-transform: scale(1,0.5);
transform: scale(1,0.5);
}
效果如下:用matrix()方法:
#pho img {
width: 410px;
height: 220px;

-webkit-transform: matrix(1,0,0,0.5,0,0);
-o-transform: matrix(1,0,0,0.5,0,0);
-moz-transform: matrix(1,0,0,0.5,0,0);
-mos-transform: matrix(1,0,0,0.5,0,0);
transform: matrix(1,0,0,0.5,0,0);

}
效果如下:再者效果一样。我们可以得出结论:scale(缩放)与matrix()方法的a,d参数有关。

rotate(旋转)

旋转就需要用到三角函数:假设旋转角度为α:rotate()方法是:
transform: rotate(α + "deg");
matrix(方法)是:
transform: matrix(cosα,sinα,-sinα,cosα,0,0);
根据公式:x' = a*x + cy + e = x*cosα - y*sinα;y' = b*x + dy + f = x*sinα + y*cosα;举例:scale(30deg)
#pho img {
width: 200px;
height: 100px;

-webkit-transform-origin: 50px 255px;
-webkit-transform: rotate(30deg);

}
效果如下:用matrix()方法:matrix(0.866025,0.500000,-0.500000,0.866025,0,0)
#pho img {
width: 200px;
height: 100px;

-webkit-transform-origin: 50px 255px;
-webkit-transform: matrix(0.866025,0.500000,-0.500000,0.866025,0,0);

}
效果如下:效果一样。得出结论:假设旋转角度为α,scale(α + "deg")就相当于matrix(cosα,sinα,-sinα,cosα,0,0)

对于ie8兼容

ie8兼容写法:filter: progid:DXImageTransform.Microsoft.Matrix(enabled=true, sizingMethod='auto expand', M11=0.866025404, M12=0.5, M21=-0.5, M22=0.866025404) ;四个参数:M11、M12、M21、M22分别表示cos(旋转的角度)、-sin(旋转的角度)、sin(旋转的角度)、cos(旋转的角度)。enabled: 表示设置或检索滤镜是否激活。true表示激活检索,fale表示不激活检索。sizingMethod: 表示设置或检索滤镜作用的对象的图片在 对象容器边界内 的显示方式。
crop : 剪切图片以适应对象尺寸。

     image : 默认值。增大或减小对象的尺寸边界以适应图片的尺寸。

     scale : 缩放图片以适应对象的尺寸边界。
auto : 自动适应容器大小。

skew(拉伸)

拉伸也用到三角函数,不过是tanα,与b,c两个参数有关,(y轴倾斜在前,x轴倾斜在后):
transform: matrix(1,tan(αy),tan(αx),1,0,0);
根据公式:x' = ax + cy + e = x + tan(αx);y' = bx + dy + f = tan(αy) + y;也就相当于skew(αx + 'deg',αy + 'deg')的写法。其中,αx就是在x轴方向上的倾斜角度,αy就是在y轴方向上的倾斜角度。举例:skewX(-45deg)
#pho img {width: 200px;height: 100px;-webkit-transform-origin: 50px 255px;-webkit-transform: skewX(-45deg);}
效果如下:用matrix()方法:matrix(1,0.000000,-1.000000,1,0,0)
#pho img {width: 200px;height: 100px;-webkit-transform-origin: 50px 255px;-webkit-transform: matrix(1,0.000000,-1.000000,1,0,0);}
效果如下:得出结论:拉伸与b,c参数有关,即:skew(αx + "deg",αy + "deg")相当于matrix(1,tan(αy),tan(αx),1,0,0)matrix()主要用于镜像

认识三维立体3D

3D立体坐标图:

通过rotateX()、rotateY()、rotateZ()认识3D立体

在现实生活中:rotateX()就如:rotateY()就如:而rotateZ()就如:

perspective属性

perspective意思是透视、视角。这个属性允许你改变3D元素是怎样查看透视图。CSS33D transform的透视点是在浏览器的前方。用translateZ: length;更容易理解,当值越在时,越远离视觉,当值越小时,越接近视觉。定义时,它是一个元素的子元素,透视图,不是元素本身。<div-------------元素<box1---子元素需为div设置perspective属性,作用于box1,而不是div本身。
<!DOCTYPE html><html lang="zh"><head><meta charset="utf-8"><title>2D/3D转换属性</title><style>#div1{position: relative;height: 150px;width: 150px;margin: 50px;padding:10px;border: 1px solid black;perspective:90;-webkit-perspective:90; /* Safari and Chrome */}#div2{padding:50px;position: absolute;border: 1px solid black;background-color: red;transform: rotateX(45deg);-webkit-transform: rotateX(45deg); /* Safari and Chrome */}</style></head><body><div id="div1"><div id="div2">HELLO</div></div></body></html>
效果如下:
#div1{position: relative;height: 150px;width: 150px;margin: 50px;padding:10px;border: 1px solid black;perspective:110;-webkit-perspective:110; /* Safari and Chrome */}
效果如下:

perspective-origin属性

perspective-origin属性允许设置3D元素的底部位置,即x轴、y轴的坐标。定义时的perspective -Origin属性,它是一个元素的子元素,透视图,而不是元素本身。定义在元素,作用于其子元素,不是在元素本身。

transform-style属性

transform-style属性规定 嵌套元素 怎样在三维空间中呈显。在子元素中设置,作用于子元素。属性值:flat--所有子元素在2D平面显示,默认值。perverse-3d()--所有子元素在3D空间显示

backface-visibility属性

backface-visibility属性规定当元素不面向屏幕(背面)时,是否可见。当旋转元素时,不想看到其背面时,适用。属性值:visible 背面是可见的。hidden  背面不可见。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: