刚接触完css3的3D变换,感觉确实十分华丽,趁着热乎劲,把感想和理解记录下来。如有不对,欢迎指正。
CSS3中提供了2D和3D两种变换方式,所谓的变换主要就是位移和旋转,2D和3D的区别大概就是有没有Z轴方向的变换,仅此而已。
所以,为了后面更好的理解3D变换,我们先说一说2D的变换。
上面两种方法是2D变换的常用方法,一个对应位移,一个对应旋转,当然还有其他的,这里就不展开,先只说说这两个。具体语法是这样的,比如我们想变换一个div。
#div1{transform:translate(100px,100px);}
#div2{transform:rotate(50deg);}
transform是css3提供的一个属性,专门用于图形变换,这个属性现在可能得到了大部分浏览器的支持,但3D效果用到的后面几种属性,还是需要做兼容,为了节省时间,讨论技术本身,后面就不照顾兼容了。
言归正传,上面两个方法光从参数也很容易理解,translate()是位移方法,分别朝x轴方向,y轴方向移动一段距离,距离可以为负。rotate()是旋转方法,会绕原点顺时针旋转一个角度。那么问题来了,原点在哪?既然是变换,必须得有参考系,这才有准确的变换效果,所以,无论2D还是3D,找准坐标系,找准坐标系,找准坐标系。因为很重要,所以说三遍。
一般来说,原点默认为元素中心点,当然这个原点也是可以调整的,通过这个属性 transform-origin:50% 50%; 这里的50% 50%表示的就是中心默认的位置,可以改成其他的,比如说左上角就应该写成 tansform-origin:0% 0%; 这样就可以调整原点了。
了解完2D,进阶一下,transform属性同样可以进行3D变换,简单来说就是分别针对x,y,z进行设置。
#div1{
transform:translateX(100px) translateY(100px) translateZ(100px) rotateX(30deg) rotateY(30deg) rotateZ(30deg);
}
旋转部分,需要特别说明一下,rotateX()表示绕X轴旋转的角度,这个变换,整个坐标系会跟着一起旋转,所以找不到原点得是多糟糕的事情,坐标系永远是跟随我们的元素的,每个元素都有自己的坐标,以初始状态来说,原点在元素中心,x轴正方向从原点水平向右,y轴正方向从原点竖直向下,z轴正方向则是从原点朝向我们的屏幕,也就是说,我们的元素正对的方向就是它自己的z轴方向,这一点千万要记好。
因为transform归根结底只是个属性,所以重复的transform只会覆盖,缩写形式就是上面这种,需要注意的是中间用空格隔开而不是逗号。另外,个人理解,transform从中文上来说,应该是“变换成”,而不是“变换”,它表现的是变换完成之后的样子。
完成了上面的变换,有3D效果了么,我们看个demo。
这里还没有进行变换,接下来我们加入变换的属性。
我们发现,它确实变形了,但是,和我们想象中的3D效果相差甚远,甚至可以说完全是一个平面效果啊。
其实css3的3D效果,是靠浏览器通过计算,渲染,最后模拟出来的一个三维效果。如果要模拟的像,可以欺骗人的眼睛,那必须要考虑一个东西,就是透视,或者说景深,再通俗点就是近大远小。只有满足这个,css3的3D变换才有3D的效果,不然即使确实进行了3D变换,浏览器也会把它投影成一个平面的,完全没有3D效果。那怎么给它增加一个透视或者说景深呢,很简单,一个属性就可以搞定。
perspective:500;
perspective属性就是所谓的透镜属性,后面的数字单位是像素,用来模拟视角离元素的距离,给最外围的元素设定好这个属性,里面的元素在景深方向有所变换时,就能准确表现出近大远小。
我们来试一下。
OK,完美,一个平面的元素,现在获得了3D的变换效果,通过几个div的不同的旋转变换,和位移,我们很容易就组合出一个正方体,这里的话要注意坐标系会跟着元素一起动的,不过它的Z轴方向一定是div正面朝向的位置,为什么一定要强调正面,是因为3D变换可以让他旋转180度,它的背面可以被我们看到,这个时候,Z轴方向就相反了。而正面,就是我们可以放内容的那个面。
如果我们组合出了一个立方体,想要它动起来,该怎么做?“立方体”是由6个div拼成,每个又有自己独立的坐标系,通过统筹他们协作变换完成这个效果,想想都让人觉得不可能。那有没有简单的方法,有,给组合体外面套一个div,我们只要旋转变换它,里面的子元素,自然也跟着旋转了。所以,在我的理解里,组合体就是一个不能运动的死物,想要动效的话,就得给它们一个“舞台”,我们通过操作舞台,就可以全方位展示,运动我们的组合体。所以我们获得了一个三层结构,最外层的透镜,里面的舞台,和舞台里的组合体。在一些大牛的博客里,可能更倾向于把它们叫做“镜头”,“空间”和“物体”。这个就是实现3D效果的基础。
我最后完成了一个立方体,并用一个div作为舞台包裹了它,想通过旋转舞台,看看其他角度的立方体,结果出现了这个情况。
立方体变成了一个平面了!为什么会这样?其实细想一下也很容易理解,div本来就是一个平面元素,所以立方体直接被它“压扁”了。舞台空间不够,也就装不下我们的展示物,所以我们要给舞台扩容,给它添加一个属性就可以解决这个问题。
transform-style:preserve-3d;
这个属性的意思是,给子元素保留3D位置,如果你不设定,那就默认不保留,也就是子元素都以平面显示。
添加完这个属性我们来看一下。
OK,立方体就出来了。
以上就是我对最基础3D效果的理解,3D效果当然不可能全都这么简单,有一些东西我没有涉及,比如perspective-origin,体会不深不敢妄谈,而且许多3D技巧我还没有掌握,后面如果再有所体会,一定分享经验。