CSS Transform
September 23, 2014
知识点
perspective-origin
默认在50%,50%- transform不影响文档流
- 多次transform函数作用时,后一次变换的坐标系为上一次变换完毕后的坐标系
Perspective 视点
To activate 3D space, an element needs perspective. This can be applied in two ways: using the transform property, with the perspective as a functional notation. 首先为了激活3D空间,需要给元素加上视点(perspective),有两种形式:用transform属性,然后把perspective当做一个函数
transform: perspective( 600px );
或者直接使用perspective属性:
perspective: 600px;
两种形式都会激活一个3D空间,但是他们是有差别的.函数符号可以直接给单个元素应用3D变换。比如上面例子左侧的。但是当用在多个元素上时,他们并不会作用在一起,而是分别对每个元素应用,这样看起来就不是我们预期的,比如下图的例子。这种情况下,我们需要使用perspective到他们的父元素上,这样每个子元素就会共用这个视点。他们看起来就像是一个统一的3D系统。
perspective的值决定3D效果的强度。你可以把它想象成与目标物体的距离,它的值越大,你离目标越远,反之亦然。perspective: 2000px;
会产生一个微弱的3D效果,就想我们在很远的地方拿望远镜来看的,perspective: 100px;
产生一个强烈的3D效果,就想近距离观察一个很大的物体。
3D空间的变换点(消失点)默认是在物体的中央,你可以通过perspective-origin
来改变这个位置:
perspective-origin: 25% 75%;
3D变换函数
3D变换和2D用同一个属性:transform,如果你对2D变换比较熟的话,那3D你看起来也不会太陌生:
- rotateX( angle )
- rotateY( angle )
- rotateZ( angle )
- translateZ( tz )
- scaleZ( sz )
与translateX在X轴上平移元素类似,translateZ在Z轴上平移元素,Z轴方向是这样的:屏幕背后是负的,屏幕前面是正的,距离屏幕越远,数值越大。
rotate函数可以使元素在相应的轴上旋转。这个和直觉有点不一样.用rotateX( 45deg )
会使顶边向后移,底边向前移。
还有三个简写的方式:
- translate3d( tx, ty, tz )
- scale3d( sx, sy, sz )
- rotate3d( rx, ry, rz, angle )
These foo3d() transform functions also have the benefit of triggering hardware acceleration in Safari. Dean Jackson, CSS 3D transform spec author and main WebKit dude, writes
实质上,任意的有3d操作的的函数都会触发硬件加速,即使它只做了2d变换,或者啥也没干。注意这只是目前的行为,未来可能会改变(所以我们没有记录下来,也没有鼓励这么做)。但在某些情况下这是很有用的,可以显著提升渲染性能。
为了简单期间,这些demo只用了最基本的transform函数,但如果要用到生产环境下,确保用的是foo3d()函数来获取最佳的性能。
Matrix 简要解释
假设每一个列是一个点向量,前三行的最后一个数决定平移的量,最后一行的前三个元素不是用来做变换位置的,他们是用来做视点的投影用的。If (as your question suggests) the convention is that points are column vectors, and the last elements of the first 3 rows determine the translation, then the first 3 elements of the bottom row are not a positional offset: the 4th row of a transformation matrix is used for perspective projection, which is how the camera maps 3D points onto the 2D viewport. A sketch of how the 4x4 matrix is used to map points:
result = 4x4 matrix * point
[ x' ] [ Rxx Rxy Rxz Tx ] [ x ]
R** is the rotation/scaling matrix
[ y' ] [ Ryx Ryy Ryz Ty ] [ y ]
= * -> T* is the translation vector
[ z' ] [ Rzx Rzy Rzz Tz ] [ z ]
P* fixes the camera projection plane
[ w' ] [ Px Py Pz Pw ] [ w ]
-> x' = dot_product3([Rxx,Rxy,Rxz], [x,y,z]) + Tx * w
-> y' = dot_product3([Ryx,Ryy,Ryz], [x,y,z]) + Ty * w
-> z' = dot_product3([Rzx,Rzy,Rzz], [x,y,z]) + Tz * w
-> w' = dot_product4([Px,Py,Pz,Pw], [x,y,z,w])