likes
comments
collection
share

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

作者站长头像
站长
· 阅读数 56

前言

绘制一个正方形,这个很简单,只要给这个元素设置一个相等的宽高即可。

.square {
    width: 200px;
    height: 200px;
    
    border: solid 1px gray;
}

若要绘制一个立方体呢?这个貌似就不是个简单的事情了。

本文将带大家一起绘制一个立方体以及如何让这个立方体旋转起来。

正方体是什么?

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

正方体也叫正六边体。它有6个面,每个面的面积都相同。

立方体绘制

要制作3D效果(立方体),首先要知道web浏览器是怎样确定坐标系的,如图:

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

注意: x轴平行,y轴垂直,z轴指向正对你的屏幕。z轴的零点就是屏幕所在的平面。

正方体有6个面,这六个面在这个3D空间坐标系中都有对应的位置。这也方便我们后面对每一个面进行移动。

HTML结构

<div class="cube-wrap">
  <div class="cube">
    <div class="front"></div>
    <div class="back"></div>
    <div class="left"></div>
    <div class="right"></div>
    <div class="top"></div>
    <div class="bottom"></div>
  </div>
</div>

在这之前,我们先简单了解以下属性:

1、perspective

决定了z=0平面和用户之间的距离

2、perspective-origin

决定了查看者正在查看的位置

3、transform-style

设置元素的子元素是位于3D空间中还是在元素的平面中被平展。

4、transform-origin

用于设置元素转换的原点

5、transform

允许您旋转、缩放、倾斜或转换元素

想更直观的感受这些属性设置后的效果,可以在MDN查看。

先把公共样式写出来

.cube-wrap {
  position: relative;
  /* 3D 元素的透视效果 */
  perspective: 800px;
  /* 规定 3D 元素的底部位置 */
  perspective-origin: 50% 100px;
}

.cube {
  position: relative;
  width: 200px;

  transform-style: preserve-3d;
}

.cube div {
  position: absolute;
  width: 200px;
  height: 200px;
}

初始状态,这6个容器是重叠在一起的。

transform-origin默认值是center center 0。示意图如下: 【CSS魔法】如何使用CSS绘制一个酷炫的立方体

这个属性很重要,设置不同的原点,所需要的转换效果不同,所以我们绘制立方体的方法也不止一种。

本文会介绍几种绘制方法。

旋转基线不变

1、先位移再旋转

看个草稿图,便于理解是如何进行3D转换的。

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

初始状态下,6个面是堆叠在如上图所示的切面位置。通过3D转换方法,将6个面分别移动到对应位置。

.left {
    transform: translateX(-100px) rotateY(-90deg);
}

.right {
    transform: translateX(100px) rotateY(90deg);
}

.top {
    transform: translateY(100px) rotateX(-90deg);
}

.bottom {
    transform: translateY(-100px) rotateX(90deg);
}

.front {
    transform: translateZ(100px);
}

.back {
    transform: translateZ(-100px) rotateY(180deg);
}

大胆发挥你的空间想象能力~

2、先旋转再位移

以左、右面为例

.left {
  transform: rotateY(-90deg) translateZ(100px);
}

.right {
	transform: rotateY(90deg) translateZ(100px);
}

详细分析:

左面-left

1、先沿Y轴向左旋转90度

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

到此就很一目了然了~

2、再沿Z轴正方向移动100px

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

右面-right

1、沿Y轴向右旋转90度

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

2、再沿Z轴正方向移动100px

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

其他面的转换思想都一样。

.top {
    transform: translateY(100px) rotateX(-90deg);
}

.bottom {
    transform: translateY(-100px) rotateX(90deg);
}

.front {
    transform: translateZ(100px);
}

.back {
    transform: translateZ(-100px) rotateY(180deg);
}

旋转基线改变

1、旋转

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

此时以原始堆叠面如图红色区域。以下所有的旋转和位移都以这个面作为参考系。

.left {
  transform-origin: left center;
  transform: rotateY(-90deg);
}

.right {
  transform-origin: right center;
  transform: rotateY(90deg);
}

.top {
  transform-origin: center top;
  transform: rotateX(90deg);
}

.bottom {
  transform-origin: center bottom;
  transform: rotateX(-90deg);
}

.front {
  transform: translateZ(200px);
}

.back {
  transform: rotateY(180deg);
}

注意:这样制作的立方体在添加旋转动画时,它会以旋转基线的面进行旋转。

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

2、先旋转再位移

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

.front {
  transform: translateZ(100px);
}

.back {
  transform: rotateY(180deg) translateZ(100px);
}

.right {
  transform: rotateY(90deg) translateX(100px);
  transform-origin: right center;
}

.left {
  transform: rotateY(-90deg) translateX(-100px);
  transform-origin: left center;
}

.top {
  transform: rotateX(-90deg) translateY(-100px);
  transform-origin: center top;
}

.bottom {
  transform: rotateX(90deg) translateY(100px);
  transform-origin: center bottom;
}

这样一个立方体就被制作出来了。

动画

接下来就是让这个立方体动起来吧~

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

水平方向旋转

.cube {
    animation: spin 5s infinite linear;
}

@keyframes spin {
  from {
    transform: rotateY(0);
  }
  to {
    transform: rotateY(360deg);
  }
}

垂直方向旋转

.vertical {
  transform-origin: 0 100px;
  animation: spin-vertical 5s infinite linear;
}

/* 调整文字正向展示 */
.vertical .top {
    transform: rotateX(-270deg) translateY(-100px);
}

.vertical .back {
    transform: translateZ(-100px) rotateX(180deg);
}

.vertical .bottom {
    transform: rotateX(-90deg) translateY(100px);
}

/* 垂直方向上的动画 */
@keyframes spin-vertical {
  from {
    transform: rotateX(0);
  }
  to {
    transform: rotateX(360deg);
  }
}

其他方向旋转

同时沿水平、垂直方向旋转

.other {
  transform-origin: 100px 100px;
  animation: spin-other 5s infinite linear;
}

/* 其他方向上的动画 */
@keyframes spin-other {
  from {
    transform: rotateX(0) rotateY(0);
  }
  to {
    transform: rotateX(360deg) rotateY(360deg);
  }
}

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

开箱动画

场景描述:鼠标移到这个立方体上,最上面的盖子打开,并且里面的小立方体浮动上来。

<div class="cube-wrap">
  <div class="cube horizontal">
    <div class="front">正面</div>
    <div class="back">反面</div>
    <div class="top">上面</div>
    <div class="bottom">下面</div>
    <div class="left">左面</div>
    <div class="right">右面</div>
    <i class="front">gift</i>
    <i class="back">gift</i>
    <i class="top"></i>
    <i class="bottom"></i>
    <i class="left">gift</i>
    <i class="right">gift</i>
  </div>
</div>

css

/* hover transformations */
.horizontal:hover div.top{
  transform: translateZ(100px) rotateX(-210deg);
  transform-origin: top center;
}

.horizontal:hover i{
  top: -200px;
}

【CSS魔法】如何使用CSS绘制一个酷炫的立方体

完整代码请看在线demo

结语

这真的考验一个人的空间想象能力,每个面的各种旋转角度,移动方向,真的死了我好多脑细胞。

可以和我之前的一篇flex布局实践篇 | 骰子结合起来实现一个立体的骰子。

小问题:就是骰子每一面设置了圆角,在立体空间中就会造成每一个角上都会有空隙。有什么好的方法解决吗?

参考文章:

转载自:https://juejin.cn/post/7212101184709181497
评论
请登录