CSS 3D:立方体 - 第1部分
#html #css #3d #cube

这是在CSS中创建的立方体:

这是CSS和HTML可以一起做的 - 没有JavaScript的帮助。而且那东西也旋转 - 如果您还没有,请继续单击中间的三角形。

现在您可能会在思考这三件事之一:

  1. 圣馄饨,蝙蝠侠! CSS可以做3D吗?哇!

  2. 1970年代。他们希望自己的技术退缩 - 因为这不会使他们公正。

  3. 这是在网络上大约这些天的所有事物面前飞行的。您要么要使用平坦的极简主义 - 要么三。

是。是的,是的。

在过去三年中,CSS中的3D形状一直是我的痴迷 - 这真是太疯狂了。但是我也很痛苦地意识到它不能做什么。对于初学者而言,“多边形计数”是有限的 - 通常,CPU开始以约500个物体(至少在我4岁的桌面上)窒息。因此,这充其量就像90年代中期的图形。另外,您必须自己定位每个“多边形”中的每一个。因为搅拌机不是。 JavaScript为Web设计师提供了创建3D固体(例如Thrix Js)的更轻松的方法 - 如果您打算在商业上进行此操作,则应使用。我,我这样做是为了娱乐 - 挑战。我是一个疯狂的科学家 - 强调疯狂,并且在该领域没有实际的学术教育。只是我在这里和那里挖掘的知识片段,同时浏览了世界上森林的错误末端,以及我自己的邪恶实验的果实。因此,您可能会看到我写一些纯粹的亵渎,牺牲的代码,这与实际专家的教义有关。我更喜欢Flexbox而不是网格 - 并且不要想自己是专家。我对形状,颜色,刻字,图标等看起来有趣的想法也有自己的想法 - 与当今的趋势完全不符。因为,正如我之前所说的,这只是为了娱乐 - 了解什么可能,有效,而不是正确,优雅,现代或商业上可行的东西。

好吧。您已被警告。

还有我吗?

计划

立方体仅仅是开始。入口处是一个无尽乐趣的三维兔子洞。有棱镜和金字塔。气缸。锥!球体,球体和更多球。 Toruses。哲学家甚至从未梦想过的多面体 - 您认为您在高中时留下的数学公式。哦,恐怖!哦,喜悦!

(我建议您在看完后停下来,这有点像CPU猪)

但是,在我们首先进入代数的迷宫之前,让我们尝试一些简单的东西。让我们坚持熟悉的角落。追踪回到我们开始的地方。

盒子

首先,让我们快速回顾一下我们对盒子的了解:

  • 它有6个面孔(因此,它是由:六面体)

  • 它的所有脸都是正方形:直角,甚至在周围的两侧

  • 所有面孔彼此完全垂直(即以90度的角度)

在我们的HMTL文件中,让我们创建6个墙壁,分组为.Cube,并将其设置在.scene中。

如果您的代码编辑器具有EMMET扩展名,则可以输入:

.scene>.cube>.wall*6

没有空间 - 然后:

  • 如果您在Codepen上,请按Tab

  • 如果您正在使用VSCODE,请按Enter

这应该产生:

<div class="scene">
  <div class="cube">
    <div class="wall"></div>
    <div class="wall"></div>
    <div class="wall"></div>
    <div class="wall"></div>
    <div class="wall"></div>
    <div class="wall"></div>
  </div>
</div>

另外,只需输入或复制上面的代码。

现在,我们需要在每个墙上手动添加一个额外的类,以指它的位置:

  1. Back

  2. top

  3. 底部

在墙类别旁边的引号中键入它们 - 仅有空格分开。

您的文件应该看起来像这样。

<div class="scene">
  <div class="cube">
    <div class="wall front"></div>
    <div class="wall back"></div>
    <div class="wall left"></div>
    <div class="wall right"></div>
    <div class="wall top"></div>
    <div class="wall bottom"></div>
  </div>
</div>

现在已经准备好了...

那个工程

前往您的CSS。首先,身体。即使您使用的是codepen,它跳过了样板 - 因此,您的html中没有明确说明身体标签,它也可以在那里进行样式:

body {
  margin: 0; /* don't want a margin on my background*/
  box-sizing: border-box; /* borders as a part of the object's dimensions*/
  background-color: black; /* hence the margin:0*/
  display: grid; /* mostly for the ease of centering content */
  place-items: center; /* centered horizontally AND vertically at once*/
  min-height: 100vh; /* so that there is enough room to center vertically */
  font-size: .5vh; /* a font-size that scales with the viewport */
  filter: drop-shadow(0 0 10px lime); /* adds a green glow to everything*/
}

请注意,该演示是一个孤立的,独立的站点 - 因此,为简单起见,我将身体用作容器/包装器。如果这只是较大网站的一部分,那么身体只需要:

margin: 0; /* don't want a margin on my background*/
box-sizing: border-box; /* borders as a part of the object's dimensions*/

所有其余的都可以降级为.container/.wrapper。

另外,您可能想知道为什么我设置了一个字体大小这么小。除了霍克斯外,这对任何人都不可读。如果鹰可以阅读。不过,事实不是文字。

.scene {
  width: 100em; /* 100 units of the font size, mimiclomg percentages */
  aspect-ratio: 1; /* so the height matches the width, producing a square*/
  position: absolute; /* independent from any neighboring containers */
  perspective: 250em; /* sets the distance of the perspective */
}

看,这就是字体大小的用途。我本可以使用像素 - 但随后立方体不会扩展。当然,除非我在媒体上去镇上。我也可以使用百分比 - 但是看到,百分比令人困惑。有时,他们指容器的父母的大小,有时是指容器本身。这雪球陷入了一堆问题。使用100EM,您将获得针对主容器量身定制的一致比例 - 在这种情况下,确实是.scene。

这也使我解放了一个立场:绝对。有了百分比,我必须给它立场:相对 - 使其成为其任何一个孩子的参考点(意味着,如果将孩子的宽度设置为100%,则为100%。场景,不是身体)。立场:绝对有很多自由。容器可以位于体内任何地方,不仅在其最接近的前身旁边或之下。它可以免费占用已经有无数其他容器的空间。

例子:

.scene * { /* meaning everything nested inside the .scene */
  position: absolute; /* everything can go everywhere */
  inset: 0; /* occupies full width & height of its parent container */
  transform-style: preserve-3d; /* makes sure that each container nested inside the .scene tag treats its nested content as a 3D object rather than a 2D projection */
}

此设置意味着.scene中的任何容器以及该容器中的任何容器,任何数量的容器 - 每个容器都可以占用可用空间的100%,没有任何边距。

这也是我们遇到了整个3D Kerfuffle中最重要的属性:

变换风格:preserve-3d;

透视实际上是可选的。它有助于呈现和强调三维 - 但不是实现3D幻想的唯一方法:

另一方面,

保存3D。实际上确保事物为3D。如果不使用它,则将转换式默认为平坦 - 因此,每个容器都将其内容视为悬浮在3D空间中的元素,而只是将其视为平坦的投影。像电视屏幕:

使用多维数据集,毛刺甚至并不特别吸引人。是的,在必要时保存3D。

现在,我们如何给墙壁一些风格:

.wall {
  border: 3em solid white; /* a white border lining the edges */
}

我说了一些风格,而不是某种风格;)巨大的差异。您可能还注意到我省略了所有墙壁的.Cube。我们稍后再解决。

现在您应该看到这样的东西:

A transparent square with a white, sligthly glowing border against a black backdrop

在黑色背景下,有一个白色边框的正方形,发光绿色。或者,相反,彼此顶部的六个平方正方形,被困在2D平面上。

有两种方法可以释放它们 - 并将它们的形状结合在一起形成一个立方体。

转换

正方形可以改变位置。他们可以移动:

  1. 左右

  2. 上下

  3. 最值得注意的是,朝着你和远离你

或,使用技术术语:您可以翻译它们 - 沿三个轴:

  1. 水平轴x

  2. 垂直轴y

  3. 应用轴z

这是实践中的样子:

类似地,您可以沿X,Y和Z轴(又称旋转)将它们转动:

您会注意到,在Z轴上旋转墙壁使其简单地旋转。这是因为壁沿X和Y轴伸展,并且不会延伸到第三维。它是完全且绝对平坦的,您不能通过CSS给它厚度。

更重要的是,笛卡尔坐标系与墙一起移动并转弯。没有X,Y和Z轴的中央静态集。从对象变换的角度观察转换。

好吧,足够旋转,不想头晕,对吗?让我们开始移动,然后 - 从3D的背景下对我们来说最有趣的两堵墙开始:将前壁带到最前沿,然后向后推。

.front {
  transform: translateZ(50em); /* pulls the wall closer to the viewer*/
}

请注意,我们将墙移到了50em-父装容器尺寸的一半。这是为了对称性 - 因为我们将向相反的方向推动后壁。

.back {
  transform: translateZ(-50em); /* pushes the wall away from the viewer*/
}

现在,他们彼此之间有100em(距离剩下的父容器的中心50em)。创建100em by 100em by 100em的前两个步骤。

现在,这太棒了 - 但是,我们如何将右墙一直到右侧,而左侧的左侧是立方体的左端?全部转换:Translatex确实是使它们朝那个方向踩踏,而Rotatex只会使它们站在适当的位置(并面对错误的方向,而我们在我们的位置:向上而不是正确)。

>

看,旋转墙将墙锁定在适当的位置,就像门上的两个铰链一样,两端连接在一起 - 既然x是水平轴,则墙壁可以向上和向下旋转的唯一方向。

如果要向左转,则锁定垂直轴:rotatey

另外,您可以链变换:首先,旋转 - 然后翻译(用空格而不是逗号分开)

.left {
  transform: rotateY(90deg) translateZ(50em);
}

.right {
  transform: rotateY(-90deg) translateZ(50em);
}

...或首先翻译,然后旋转。但这是另一个故事和自己的蠕虫罐头。现在,让我们分析这里发生的事情:

  • 。左墙向左转,然后向前移动

  • 同样,右墙将墙右转,然后将其向前推

注意:正如我之前提到的,从对象的角度看,转换总是被视为。它的左边是您的右边 - 就像一个站在您面前的人一样 - 因为它面对您。在转弯并向前移动之后,这意味着它向前 - 您看起来像是向右移动。

您知道的越多...

说到哪个:我们已经知道Translatex抬起墙,所以让我们这样做,然后按照翻译进行操作:

.top {
  transform: rotateX(90deg) translateZ(50em);
}

.bottom {
  transform: rotateX(-90deg) translateZ(50em);
}

最后,这里是:

立方体

在其所有三维荣耀中:

A 3D cube with transparent walls and white borders, viewed with a single-point perspective

头脑笨拙,不是吗?

如果您的头还没有旋转...我们也会旋转该立方体吗?

.cube {
  animation: spin 6s linear infinite; /* adds a spinning animation */
}

@keyframes spin { /* the details of the animation: */
  100% { /* at the end point of the animation */
    transform: rotateY(360deg); /* ...the cube will have make a full 360 degree turn */
  }
}

它起作用了吗?你看到了什么?你喜欢你看到的吗?您是否为更多?

感到兴奋吗?

因为有更多...