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

CSS3 3D转换入门篇

2015-12-29 20:31 603 查看

概述

为了对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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: