我们平常前端编程都是在一个二维平面内,那么如何做一个3D效果呢?比如创建一个立方体,像下面这样:
我自己总结了一下,大概分为以下几步:
- 创建一个3D窗口
- 确定观察视角(比如我们是从正中间看,还是从左上或右下看)
- 指明变换是在三维的维度上变换。
- 写具体的变换内容。
接下来,我将会以上图立方体为例子,一步步地向大家演示如何实现。
一、创建一个3D窗口
请大家暂停思考一下:为什么需要创建一个3D窗口?
先思考,先别往下看哦!
我们平常编程都是在浏览器窗口这个二维平面内,浏览器默认的也是二维。如果想要写3D效果,需要告诉浏览器:我现在要写3D 的东西了,所以创建一个3D的窗口。
如何创建?
perspective
CSS属性
perspective
指定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果。 z>0 的三维元素比正常大,而 z<0 时则比正常小,大小程度由该属性的值决定。
翻译成人话就是:perspective属性告诉浏览器,这块里的内容是3D的,遵循近大远小的透视原理。
注意:当为元素定义 perspective 属性时,其子元素会获得透视效果,而不是元素本身。
所以,我们的如果第一步是创建一个3D区域,上面那个正方体第一步代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>cube</title>
<style>
*{
margin: 0;
padding: 0;
}
html,body,.wrap{
width: 100%;
height: 100%;
}
.wrap{
background-color: pink;
/* 使其子元素水平居中和垂直居中 */
display: flex;
justify-content: center;
align-items: center;
}
.cube{
position: relative;
width: 300px;
height: 300px;
/* 创建3D场景 */
perspective: 800;
-webkit-perspective: 800;
}
.epage{
list-style: none;
width: 150px;
height: 150px;
background-color: #000;
position: absolute;
top: 0;
left: 0;
border: 1px solid #fff;
font-size: 80px;
font-weight: bold;
text-align: center;
color: #fff;
}
</style>
</head>
<body>
<div class="wrap">
<ul class="cube">
<li class="epage">1</li>
<li class="epage">2</li>
<li class="epage">3</li>
<li class="epage">4</li>
<li class="epage">5</li>
<li class="epage">6</li>
</ul>
</div>
</body>
</html>
效果如下:
二、确定观察视角
观察视角是指,观察者(其实就是我们)看这个3D场景的视角,比如从上下左右还是中间看。
这里的上下左右中间使相对于当前3D场景的角度。(大家不必纠结在网上搜到的什么消失点之类的东西,透视原理的内容,没必要抠那么细)
我们这里暂定观察视角为正中间
perspective-origin: 50% 50%;
所以我们的css代码变成了
.cube{
position: relative;
width: 300px;
height: 300px;
perspective: 800;
-webkit-perspective: 800;
perspective-origin: 50% 50%;
-webkit-perspective-origin: 50% 50%;
}
三、指明变换是在三维的维度上变换
做正方体肯定会用到变换transform
,但是transform有二维的(比如rotate()),也有三维的(比如rotateX()、rotateY()、rotateZ())
所以,我们要告诉浏览器,在3D场景里的transform都是基于三维的transform。
transform-style: preserve-3d;
官方文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform-style
所以我们代码就变成
.cube{
position: relative;
width: 300px;
height: 300px;
perspective: 800;
-webkit-perspective: 800;
perspective-origin: 50% 50%;
-webkit-perspective-origin: 50% 50%;
transform-style: preserve-3d;
}
四、写具体的变换内容
.epage:nth-child(1){
}
.epage:nth-child(2){
transform-origin: left;
transform: rotateY(90deg);
}
.epage:nth-child(3){
transform-origin: right;
transform: rotateY(-90deg);
}
.epage:nth-child(4){
transform-origin: top;
transform: rotateX(-90deg);
}
.epage:nth-child(5){
transform-origin: bottom;
transform: rotateX(90deg);
}
.epage:nth-child(6){
transform: translateZ(-100px);
}
最后可以看到如下效果:
为了更清楚地看到3D立方体,我们让cube转动一下,
.cube{
position: relative;
width: 300px;
height: 300px;
perspective: 800;
-webkit-perspective: 800;
perspective-origin: 50% 50%;
transform-style: preserve-3d;
/* cube转动角度 */
transform: rotateX(30deg) rotateY(30deg) rotateZ(70deg);
}
然后就看到效果了: