CSS实现3D效果:立方体

5,820 阅读4分钟

最终效果如下



首先要给3D的元素准备一个“舞台”,因为页面本身是平面的,并不能展示出3D的效果。

通过设置透视距离,就相当于把这个区域变成了一个能表现出近大远小的“3D舞台”,在其内部就可以去做3D效果了。

<div class="container">
</div>

.container {
  height: 500px;
  background: #eee;
  perspective: 500px;   /* 设置透视距离 */
}


舞台搭好,演员上场,在container中加入一个盒子用来做正方体。设置宽高并定位到舞台中央,添加一个边框方便看到位置,设置transform-style属性,他的作用是允许box这个盒子的子元素进行3d变换

<div class="container">
  <div class="box">
  </div>
</div>

.box {
  width: 200px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  border: 1px solid #000;
  transform-style: preserve-3d;
}


正方体有六面,在box中添加六个div用来做他的六个面。

将六个面两两一组分为a, b , c三组方便描述:a1为离我们最近的‘前面’,a2就是与a1相对离我们最远的‘背面‘,b1为左侧的面,b2为右侧面,c1为顶部,c2为底部(参考文章顶部效果图)

<div class="container">
  <div class="box">
    <div class="a1">a1</div>  <!-- 前 -->
    <div class="a2">a2</div>  <!-- 后 -->
    <div class="b1">b1</div>  <!-- 左 -->
    <div class="b2">b2</div>  <!-- 右 -->
    <div class="c1">c1</div>  <!-- 上 -->
    <div class="c2">c2</div>  <!-- 下 -->
  </div>
</div>

将六个面都定位到box的正中心,设置宽高,并把文本居中

.box div {  
  width: 200px;  
  height: 200px;
  position: absolute;
  text-align: center;
  line-height: 200px;
  font-size: 30px;
}

此时的六个面相当于是重叠在x轴为0,y轴为0,z轴也为0的地方(x和y轴在屏幕上分别表现为左右和上下,z轴表示视觉上与我们的距离远近)


上面我们将每个面的宽高都设置为200px,也就是相对的两个面之间的距离应该是200px。

先来设置a1面,沿z轴向前移动100px,也就是向我们靠近100px,同时给每个面都加上一个透明的颜色方便看效果

.a1 {
  background: rgba(0, 0, 255, 0.5);
  transform: translateZ(100px);
}

然后将a2面沿z轴向后移动100px,也就是相对我们变远100px

.a2 {
  background: rgba(0, 0, 255, 0.5);
  transform: translateZ(-100px);
}

这样本来重叠的两个面,一个靠近100px,一个变远100px,两个面之间刚好200px距离

另外还应该将a2沿y轴旋转180度,也就是翻个面,将有字的这一面对着外面

.a2 {
  background: rgba(0, 0, 255, 0.5);
  transform: translateZ(-100px) rotateY(180deg);
}

此时已经看出3d效果生效了,因为近大远小的原理,虽然都是200px的长宽,离我们更近的a1面比box的边框要大出一圈,而较远的a2则要小一圈


再来设置b1,b1是左侧的面,沿x轴左移100px, 然后沿y轴旋转-90度,将写字的正面朝向左侧

.b1 {
  background: rgba(0, 255, 0, 0.5);
  transform: translateX(-100px) rotateY(-90deg);
}

相对的,b2就是右移100px,旋转正90度

.b2 {
  background: rgba(0, 255, 0, 0.5);
  transform: translateX(100px) rotateY(90deg);
}


继续设置c1,c1是顶部的面,所以沿y轴上移100px,然后沿x轴旋转90度

.c1 {
  background: rgba(255, 0, 0, 0.5);
  transform: translateY(-100px) rotateX(90deg);
}

相对的,c2为底部,沿y轴下移100px,然后沿x轴旋转-90度

.c2 {
  background: rgba(255, 0, 0, 0.5);
  transform: translateY(100px) rotateX(-90deg);
}


此时这个3D的立方体已经完成了,为了能看出更明显的立体效果,再加一些变化

回到.box的样式,将边框去除,然后增加一点角度的倾斜

.box {
  width: 200px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) rotateZ(10deg) rotateX(-30deg);
  /* border: 1px solid #000; */
  transform-style: preserve-3d;
}


最后添加一个旋转的动画

.box {
  width: 200px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) rotateZ(10deg) rotateX(-30deg);
  /* border: 1px solid #000; */
  transform-style: preserve-3d;
  animation: run 5s linear;
  animation-iteration-count: infinite;
}

@keyframes run {
  0% {
    transform: translate(-50%, -50%) rotateZ(10deg) rotateX(-30deg) rotateY(0);
  }
  50% {
    transform: translate(-50%, -50%) rotateZ(10deg) rotateX(-30deg) rotateY(180deg);
  }
  100% {
    transform: translate(-50%, -50%) rotateZ(10deg) rotateX(-30deg) rotateY(360deg);
  }
}