zoukankan      html  css  js  c++  java
  • CSS3 3D transform变换

    主要是看了这位大佬的文章,http://www.zhangxinxu.com/wordpress/2012/09/css3-3d-transform-perspective-animate-transition/,有的很大的收获,在上一个制作3D变形案例中明白了一些原理。

    首先一个立体坐标系:

    按照我的理解:

    1.认识的突破口:rotateX, rotateY, rotateZ

    3D transform中有下面这三个方法:

    • rotateX( angle )
    • rotateY( angle )
    • rotateZ( angle )

    每个轴就是一个可转动的轴承一样,

     

    rotateX(90deg),转动X轴,向上(正方向)反转90度。

    一个大佬形象的比喻就是:

    邹凯的体操单杠运动是rotateX
    单杠

    蔡依林姐姐的钢管舞是rotateY
    蔡依林-钢管舞 张鑫旭-鑫空间-鑫生活

    旋转飞刀的特技表演是rotateZ
    飞刀魔术

    于是:
    transform rotateX(45deg)的效果图 张鑫旭-鑫空间-鑫生活 transform rotateY(45deg)的效果图 张鑫旭-鑫空间-鑫生活 transform rotateZ(45deg)的效果图 张鑫旭-鑫空间-鑫生活

    2.perspective属性

    perspective的中文意思是:透视,视角!

    perspective属性的存在与否决定了你所看到的是2次元的还是3次元的,也就是是2D transform还是3D transform. 这不难理解,没有透视,不成3D.

    我们初中学美术,或者学建筑的同学肯定接触过透视的一些东西:
    3D透视 张鑫旭-鑫空间-鑫生活 3D透视 张鑫旭-鑫空间-鑫生活

    不过,CSS3 3D transform中的透视的透视点与上面两张示例图是不同的:CSS3 3D transform的透视点是在浏览器的前方

    或者这么理解吧:显示器中3D效果元素的透视点在显示器的上方(不是后面),近似就是我们眼睛所在方位!

    比方说,一个1680像素宽的显示器中有张美女图片,应用了3D transform,同时,该元素或该元素父辈元素设置的perspective大小为2000像素。则这张美女多呈现的3D效果就跟你本人在1.2个显示器宽度的地方(1680*1.2≈2000)看到的真实效果一致!!
    1680宽度像素显示器与3D transform视角大小示意 张鑫旭-鑫空间-鑫生活

     很好的讲法,用视角的距离增加3D效果。

    3.translateZ帮你寻找透视位置

    translateZ可以更明显看到3D效果,里面的参数大小对应远小近大的原理,参数越大,元素旋转后就变大,离你更“近”。

    大佬的讲解是这样:

    如果说rotateX/rotateY/rotateZ可以帮助理解三维坐标,则translateZ则可以帮你理解透视位置。

    我们都知道近大远小的道理,对于没有rotateX以及rotateY的元素,translateZ的功能就是让元素在自己的眼前或近或远。比方说,我们设置元素perspective为201像素,如下:

    perspective: 201px;

    则其子元素,设置的translateZ值越小,则子元素大小越小(因为元素远去,我们眼睛看到的就会变小);translateZ值越大,该元素也会越来越大,当translateZ值非常接近201像素,但是不超过201像素的时候(如200像素),该元素的大小就会撑满整个屏幕(如果父辈元素没有类似overflow:hidden的限制的话)。因为这个时候,子元素正好移到了你的眼睛前面,所谓“一叶蔽目,不见泰山”,就是这么回事。当translateZ值再变大,超过201像素的时候,该元素看不见了——这很好理解:我们是看不见眼睛后面的东西的!

    4.perspective视角盲区

     这个就是你视线与一个旋转的Y轴上的物体平行时,物体就消失不见。

    鑫空间里面还讲到了perspective的两种写法,如果舞台元素只有一个,最终呈现的视觉效果是一样的

    (近大远小)

    这是因为这时候的视角是以舞台元素的每一个形体为透视元素,当舞台上有多个形体,就想你的面前一下子有很多半开着的门(Y轴旋转45度),你的视线到达这些门的角度和距离都是不同的,所以效果也就不一样了。

    5.其他

    其他我就不写我自己的理解了,直接复制大佬的讲解(有点死宅的味道=-=):

    理解perspective-origin

    perspective-origin这个属性超级好理解,表示你那双色迷迷的眼睛看的位置。默认就是所看舞台或元素的中心。有时候,我们对中心的位置是不感兴趣的,希望视线放在其他一些地方。比方说
    不同视线落地位置对应不同的perspective-origin值

    一图胜千言,屌丝男们这个应该都懂的。

    下面为立方体的实际应用透视效果图:

    perspective-origin: 25% 75%;

    立方体不同透视角度的效果 张鑫旭-鑫空间-鑫生活

    transform-style: preserve-3d

    transform-style属性也是3D效果中经常使用的,其两个参数,flat|preserve-3d. 前者flat为默认值,表示平面的;后者preserve-3d表示3D透视。

    preserve-3d符合我们真实世界的思维认识。比方说,你让妹子右转了45度,此时妹子脑袋左转45度想你吐舌卖萌,妹子的脸蛋应该和你是面对面平行的。
    妹子推到与transform rotateY 张鑫旭-鑫空间-鑫生活
    应用transform-style: preserve-3d声明的元素确实是这样表现的,但是,如果使用默认的flat值,其效果表现——恕我想象力有限——想不通:妹子的脸还是左转45度的,同时脑袋似乎移到了身体以外的地方

    因此,基本上,我们想要根据现实经验实现一些3D效果的时候,transform-style: preserve-3d是少不了的。一般而言,该声明应用在3D变换的兄弟元素们的父元素上,也就是舞台元素。

    backface-visibility

    在显示世界中,我们无法穿过软妹A看到其身后的软妹B或C或D;但是,在CSS3的3D世界中,默认情况下,我们是可以看到背后的元素(也不知可不可以透视妹子的衣服~)!
    看不到后面的软妹,哦呵呵,  backface-visibility, 张鑫旭-鑫空间-鑫生活

    因此,为了切合实际,我们常常会这样设置,使后面元素不可见:

    backface-visibility:hidden;

    实际应用-图片的旋转木马效果

    您可以狠狠地点击这里:图片的旋转木马效果demo

    建议在足够新版本的FireFox浏览器或Safari浏览器下观看,Chrome可能需要居中定位查看,下图为效果缩略图:
    图片3D旋转木马效果截图 张鑫旭-鑫空间-鑫生活

    原理:
    那些看上去很酷酷的CSS3 3D效果其实就颠来倒去那几个属性(本文提到的这几个),折腾来折腾去,这里这个效果显然也是如此。

    首先HTML结构,如下:

    舞台
        容器
            图片
            图片
            图片
            ...

    对于舞台,很简单,加个视距,比方说800像素:

     perspective: 800px;

    对于容器,很简单,加个3D视图声明,如下:

    transform-style: preserve-3d;

    然后就是图片们了。为了不至于产生类似DNA的螺旋状效果,我们让所有图片position:absolute,公用同一个中心点。

    显然,图片旋转木马是类似钢管舞旋转的运动,因此,我们关心的是rotateY的大小。

    因为要正好绕成一个圈,因此,图片rotateY值正好0~360等分,于是,如果有9张图片,则每个图片的旋转角度累加40(360 / 9 = 40)度即可。因此有:

    img:nth-child(1) { transform: rotateY(   0deg ); }
    img:nth-child(2) { transform: rotateY(  40deg ); }
    img:nth-child(3) { transform: rotateY(  80deg ); }
    img:nth-child(4) { transform: rotateY( 120deg ); }
    img:nth-child(5) { transform: rotateY( 160deg ); }
    img:nth-child(6) { transform: rotateY( 200deg ); }
    img:nth-child(7) { transform: rotateY( 240deg ); }
    img:nth-child(8) { transform: rotateY( 280deg ); }
    img:nth-child(9) { transform: rotateY( 320deg ); }

    这样就好了吗?

    No, No, No!!!

    想想看那,虽然9个绝色美女每个人的方位不一样,但都站在同一个点上,早就挤作一团,A罩都挤成C了,显然是不行的(见下图只设置rotateY)!我们需要拉开空间~~

    只设置rotateY时候,众多美女图片挤作一团

    如何拉开空间,很简单。

    想想看那:9个美女,分别面朝东南西北共9个不同方位,她们只要每个人向前走个4~5步,美女们之间的空间不久拉开了,呈现圆形了!想象一下夜空中,礼花绽开的场景~~

    这里的向前走4~5步,聪明的人应该已经知道了,就是本文提到的translateZ, 当translateZ为正值的时候,元素会向其面对的方向走去;如果元素无旋转,就会朝显示器走来!!

    现在只剩下一个问题了,美女们要向前走多远呢??

    这个距离是有计算公式滴!

    拿本demo距离,每张美女图片的宽度是128像素,因此,有如下理想方位效果图:
    旋转木马效果理想方位图 张鑫旭-鑫空间-鑫生活

    上图中红色标注的r就是的demo页面中图片要translateZ的理想值(该值可以让所有图片无缝围成一个圆)!

    r的计算很简单,有初中数学水平的人应该都会:

    r = 64 / Math.tan(20 / 180 * Math.PI) ≈ 175.8

    demo页面为了好看,图片之间留了点间距,使用的translateZ的值为175.8 + 20 = 195.8.
    旋转木马demo页面translateZ值大小

    最后的最后,要让木马旋转起来,只要让容器每次旋转40度就可以了。

    节省篇幅,具体的JavaScript操作代码就不展示了,您有兴趣可以查看demo页面源代码。

  • 相关阅读:
    GirdView实现折叠式效果
    asp.net MVC出错解决
    C#如何实现从内存中加载程序集
    从线程池看《操作系统》专业课的作用【转自杨中科学生大本营】
    JavaScript的10个非常有用的方法【转】
    JQuery最佳实践:JQuery自定义事件的应用
    C#的委托事件在winform窗体中实现传值备忘
    asp.net异步获取datatable并显示
    ASP.NET 请求处理流程【转】
    温故而知新:WinForm/Silverlight多线程编程中如何更新UI控件的值
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/7436166.html
Copyright © 2011-2022 走看看