一、概述
3D转换就是让元素在x、y、z三条轴组成的三维空间中旋转或位移。
要在平面上做立体,就得借助CSS空间坐标系
执教坐标系是一个两两垂直有序的三元线形成的三维空间,三条轴都有一个单独的单位长度并且每一条轴线有一个方向,如下图所示
那如何用平面模拟出三维的显示效果呢?这里先需要用到透视距离,也就是景深
那什么是景深,接用百度百科的解释就是在镜头前方(焦点的前、后)有一段一定长度的空间,当被摄物体位于这段空间内时,其在底片上的成像恰位于同一个弥散圆之间。被摄体所在的这段空间的长度,就叫景深。
看完上面的解释如果还是觉得难以理解的话,我们可以简单的认为在平面上的物体由于距离的远近而显示出不一样的效果,同时让人眼感觉是一个三维立体的存在。
css中使用perspective属性来设置变形元素的景深,如果需要看到效果需要配合3d转换的相关属性才行
二、样例
我们来制作一个正方体
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,body{
height: 100%;
}
body{
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
.box{
width: 300px;
height: 300px;
position: relative;
}
.box .item{
width: 300px;
height: 300px;
position: absolute;
text-align: center;
font-size: 100px;
line-height: 300px;
}
.box .item:nth-child(1){
background-color: rgba(0, 255, 0, 0.7);
}
.box .item:nth-child(2){
background-color: rgba(255, 0, 0, 0.7);
}
.box .item:nth-child(3){
background-color: rgba(0, 0, 255, 0.7);
}
.box .item:nth-child(4){
background-color: rgba(255, 255, 0, 0.7);
}
.box .item:nth-child(5){
background-color: rgba(0, 255, 255, 0.7);
}
.box .item:nth-child(6){
background-color: rgba(255, 0, 255, 0.7);
}
</style>
</head>
<body>
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
</body>
</html>
效果
我们能看到6个class为item的div元素块重叠在一起了
接下来我们对class为item的div元素块进行一些空间的位移转换和旋转,我们再来看看效果
数值为1的div块,我们让他往屏幕前移动150像素,不旋转,设置值如下
代码语言:javascript复制transform: translateZ(150px);
为了能看清楚效果,我们对class为box的元素设置如下属性
代码语言:javascript复制.box{
width: 300px;
height: 300px;
background-color: pink;
position: relative;
transform-style: preserve-3d; //让子元素在3d空间展示,如果这项不设置,默认是flat,这是所有子元素平面展示,那就没有3d效果了
transition: 1s;
}
.box:hover{
transform: rotateX(-45deg) rotateY(45deg);
}
设置完上述属性后,我们看一下效果
数值为2的div块,我们让他往屏幕右侧移动150像素,再沿着y轴旋转90度,设置值如下,
代码语言:javascript复制transform: translateX(150px) rotateY(90deg);
这里我们说明一下,transform属性的执行顺序是从右向左执行的,所以上述的执行顺序是先按y轴旋转90度,再向右侧移动150像素
效果如下
数值为3的div块,我们让他往屏幕后移动150像素,不旋转,设置值如下
代码语言:javascript复制transform: translateZ(-150px);
效果如下
数值为4的div块,我们让他往屏幕左侧移动150像素,再沿y轴旋转90度,设置值如下
代码语言:javascript复制transform: translateX(-150px) rotateY(90deg);
效果如下
数值为5的div块,我们让他往屏幕下方移动150像素,再沿x轴旋转90度,设置值如下
代码语言:javascript复制transform: translateY(150px) rotateX(90deg);
效果如下
我们可以继续增加如下属性,可以看的更加清楚
代码语言:javascript复制.box .item:nth-child(6){
background-color: rgba(255, 0, 255, 0.7);
transition: 1s;
}
.box .item:nth-child(6):hover{
transform: translateY(-300px);
}
效果如下
数值为6的div块,我们让他往屏幕上方移动150像素,再沿x轴旋转90度,设置值如下
代码语言:javascript复制transform: rotateX(90deg) translateY(-150px);
效果如下
至此,3d效果的正方体就制作完成了,当然还是有一些问题,比如3、4、5面的数值显示方向有误,主要是旋转方向的问题,我们调整一下
内容为3的元素设置如下
代码语言:javascript复制transform: translateZ(-150px) rotateY(-180deg);
内容为4的元素设置如下
代码语言:javascript复制transform: translateX(-150px) rotateY(-90deg);
内容为5的元素设置如下
代码语言:javascript复制transform: translateY(150px) rotateX(-90deg);
最后的效果如下
最后再贴上完整的源码
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,body{
height: 100%;
}
body{
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
.box{
width: 300px;
height: 300px;
position: relative;
transform-style: preserve-3d;
transition: 1s;
}
.box:hover{
transform: rotateX(-45deg) rotateY(45deg);
}
.box .item{
width: 300px;
height: 300px;
position: absolute;
text-align: center;
font-size: 100px;
line-height: 300px;
}
.box .item:nth-child(1){
background-color: rgba(0, 255, 0, 0.7);
transform: translateZ(150px);
}
.box .item:nth-child(2){
background-color: rgba(255, 0, 0, 0.7);
transform: translateX(150px) rotateY(90deg);
}
.box .item:nth-child(3){
background-color: rgba(0, 0, 255, 0.7);
transform: translateZ(-150px) rotateY(-180deg);
}
.box .item:nth-child(4){
background-color: rgba(255, 255, 0, 0.7);
transform: translateX(-150px) rotateY(-90deg);
}
.box .item:nth-child(5){
background-color: rgba(0, 255, 255, 0.7);
transform: translateY(150px) rotateX(-90deg);
}
.box .item:nth-child(6){
background-color: rgba(255, 0, 255, 0.7);
transform: translateY(-150px) rotateX(90deg);
}
</style>
</head>
<body>
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
</body>
</html>