CSS3 3D转换入门篇

来源:互联网 发布:js移动端日期选择插件 编辑:程序博客网 时间:2024/06/06 01:34

概述

为了对CSS3中的3D transform 有个基本概念,首先我们来看个Demo,由四个DIV经过3D转换而来。可以通过上下左右键来改变视角方向,+ — 键来改变视角深度。

    http://followyourheart.sinaapp.com/Demos/css3_3d_transform.html上面的Demo简单地演示了由4个div组成的空间形状,说到3D转换,最重要的是先要有坐标概念。传统2D页面中,我们知道坐标轴的大致方向如下:
在3D转换中我们常常会将袁绍向某个方向移动,或者绕某个轴旋转,其中大致的坐标系如下:
这个是3D转换的核心,下面我们再来看看相关的CSS语法与一些概念。

重要属性

perspective 与 perspective-origin

透视这一说法对于大部分刚接触的人来说确实有点云里雾里,这个属性是规定其子元素被查看的位置。打个比方,就是说假如屏幕显示的图像是一个摄像机距离其“perspective”的距离拍摄出来的。同时只要该属性值大于0,该元素的子元素即呈现被现实中3D的效果。不理解?看看下面的对比图


图中都是一大一小两个DIV,小DIV嵌套在大的里面。两图中的黄色DIV均沿X轴方向旋转了45度(至于旋转的过程,请参考之前提到的坐标轴自行脑补),但是明显第一幅图中黄色DIV只是宽度变小而已,准确来说像是投影,而第二副图却呈现出了3D的视觉效果。两者最大的区别在于“深度”,这也就是perspective属性所起的作用。外层的DIV通常我们会给它一个视角的距离与位置。

perspective 设置视角距离,perspective-origin 设置视角的偏移量默认值为perspective-origin: 50% 50%;说到这两个属性,我们首先必须要有个舞台的概念,所有3D的元素均处于舞台之中,这两个属性是设置在舞台上,来表示观看者的位置。

transform-style

这是我认为非常重要的一个属性,这是设置在3D元素上,表示它的子元素是否保留其3D转换,虽然它的作用看起来很好理解。基本用法是给某个3D元素设置transform-style: preserve-3d后,其子元素也具有3D效果。若设置为flat,这其子元素类似于投影的方式显示在父元素表面。给个对比图:

 

左侧transform-style: preserve-3d,右侧为transform-style: flat。三个DIV的关系为外层为舞台,需要指定perspective属性,内部均为3D元素,红色DIV由于其包含子元素,所以需要指定其子元素黄色DIV的显示方式。

关于TRANSFORM-STYLE的特殊用法 

还是看图做对比,找茬中去真正去理解。下图是文章一开始Demo中的内容。

    

左图中,我定义了一个“舞台”DIV,在其内部放置了四个相同大小的DIV,再将这些子DIV进行3D转换(移动与旋转),结果出现了左图这种看不明白的视图。仔细一看你会发现,下方的DIV遮住了左侧的DIV,然而左侧被遮住的部分本应该出现在前面。这就涉及到显示的优先级问题,大家都知道z-index的概念,z-index越大,就显示在越前面。从左图我们明显可以发现底部蓝色DIV的z-index是要比左侧红色DIV大的,但是这并不符合我们现实中的认知。

所以这里要用到transform-style属性,这个属性加在"舞台"上可以吗?答案是否定的,因为前面我提到过,这个属性是加在3D元素上的,所谓3D元素,本质就是舞台的子元素,所以我们需要再定义一个DIV容器,给其添加  transform-style: preserve-3d 属性,然后将四个DIV放入这个容器,这样这四个DIV就会以现实中的视距来决定内容先后顺序,而不是z-index。

 转换:

前面这些奇怪的属性介绍完了,我们就要开始转换了。转换用到一个属性 transform,使用方法为

transform: translateX(-100px) translateY(-100px) rotateX(90deg) rotateY(90deg);

注意空格,意思为沿x轴反向移动100px,向y轴反向移动100px,绕x轴旋转90度,绕Y轴旋转90度。这便是最常用的转换。更多API请参考:

http://www.w3school.com.cn/css3/css3_3dtransform.asp

以下是文章一开始提到的demo的源码,下一篇博客我会介绍一些更实用的用法与场景。

 

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title>Web 3D 入门</title></head><style>    .stage {        position: absolute;        left: 50%;        top: 50%;        margin: -200px -200px;        width: 400px;        height: 400px;        perspective: 500px;        perspective-origin: 10% 10%;    }    .container {        transform-style: preserve-3d;    }    .container div {        position: absolute;        width: 200px;        height: 200px;        color: white;        border: solid #ffef4c 2px;        font-size: 100px;        word-break: break-all;    }    .description {        text-align: center;        color: #7e2015;    }    #floor {        transform: rotateX(90deg);        background-color: lightseagreen;    }    #wall_left {        transform: translateX(-100px) translateY(-100px) rotateX(90deg) rotateY(90deg);        background-color: #b23239;    }    #wall_right {        transform: translateX(100px) translateY(-100px) rotateX(90deg) rotateY(90deg);        background-color: #12b21b;    }    #top {        transform: translateY(-200px) rotateX(90deg);        background-color: #a65efe;    }</style><body><div class="description">    <h1>Use directiion keys to change your position and "+" "-" to change your distance.</h1></div><div class="stage">    <div class="container">        <div id="wall_left">Hello</div>        <div id="floor">World</div>        <div id="wall_right">Hello</div>        <div id="top">World</div>    </div></div><script>    var LEFT = 37, RIGHT = 39, UP = 38, DOWN = 40, PLUS = 187, MINUS = 189,            container = Q(".stage")[0],            perspective = 500, originX = 10, originY = 10;    document.addEventListener("keydown", function (event) {        switch (event.keyCode) {            case LEFT:                originX -= 10;                break;            case RIGHT:                originX += 10;                break;            case UP:                originY -= 10;                break;            case DOWN:                originY += 10;                break;            case PLUS:                perspective -= 50;                break;            case MINUS:                perspective += 50;        }        perspective = perspective < 50 ? 50 : perspective;        container.style.perspective = perspective + "px";        container.style["perspective-origin"] = originX + "% " + originY + "%";    });    function Q(selector) {        if (selector.charAt(0) == "#") {            return document.getElementById(selector.slice(1, selector.length));        }        if (selector.charAt(0) == ".") {            return document.getElementsByClassName(selector.slice(1, selector.length));        }    }</script></body></html>






0 0
原创粉丝点击