【问题标题】:constructing a 3d pyramid with css用 css 构建一个 3d 金字塔
【发布时间】:2016-07-02 06:48:24
【问题描述】:

这是我目前所拥有的jsbin,下面是我正在尝试构建的图像:

这是 html,目前我只添加了金字塔的 2 个边:

<div class="pyramid-container">
  <div id="pyramid">
    <div class="base"></div>
    <div></div>
    <div></div>
  </div>  
</div>

这里是css:

.pyramid-container {
  perspective: 800px;
}

#pyramid {
  position: relative;
  transform-style: preserve-3d;
  transform-origin: 116px 200px 116px;
   padding-left: 100px;
  margin-top: 50px
}


#pyramid div:not(.base) {
  position: absolute;
    width: 0;
    height: 0;
    border-left: 100px solid transparent;  /* left arrow slant */
    border-right: 100px solid transparent; /* right arrow slant */
    border-bottom: 100px solid; /* bottom, add background color here */
    font-size: 12px;
    line-height: 0;
  opacity: .5;
}

.base {
  position: absolute;
  width: 200px;
  height: 200px;
  background-color: #ff0000;
  transform: rotateX(80deg) translate3d(0px, 10px, 0px);
}

#pyramid div:nth-child(2) {
  border-bottom-color: blue;//#e04545;
  transform: rotateX(-30deg) rotateY(0deg) rotateZ(0deg) translate3d(0px, 0px, 100px);
}

#pyramid div:nth-child(3) {
  border-bottom-color: yellow;//#ccaf5a;
  transform: rotateX(30deg) rotateY(0deg) rotateZ(0deg) translate3d(0px, 25px, 0px);
}

我正在使用 css3 创建 1 个基本矩形 div 和 4 个三角形 div。

我想要一些有关所涉及的数学以及如何定位元素的帮助。

我希望所有 4 个三角形边在顶点处相交,并将四个三角形底边定位在矩形 div 上。

我正在努力解决如何让不同三角形的点在顶点相遇。

任何人都可以帮助我解决数学问题或使用什么逻辑来实现这一点。

我不是在寻找代码,而是在寻找我应该使用的逻辑或数学。

【问题讨论】:

  • @Teepeemm 我已经添加了代码

标签: css math geometry


【解决方案1】:

首先,关于 CSS 转换的几个基本点

  • 转换的顺序很重要
  • 视角会随着容器的大小而变化(#pyramid for you)
  • 变换的原点不被继承,如果不设置transform-origin,则默认为对象的中心(包括borders等,afaict)
  • x 是水平轴,y 是垂直轴,z 是垂直于屏幕表面的轴(当您没有透视时)

然后在金字塔上:

让我们看看底角(我们称之为α)。根据角度 α 表示三角形大小,得到:

  • 宽度 = 底数
  • apothem(三角形的高度)= (1/2 Base) / cos(α)
  • 金字塔的高度 = (1/2 Base) * tan(α)

在您尝试的金字塔中,底数 = 200 像素,因此 1/2 底数 = 100 像素,Apothem = 三角形高度 = 100 像素。这迫使 cos(α) = 1 因此 α = 0° - 你将有一个扁平的金字塔。

如果你想要 α = 60°,你想要 apothem = 200px,你会得到金字塔高度 = 173.2
如果你想要 α = 45°,你想要 apothem = 141px,你会得到金字塔高度 = 100
等等

现在您知道参数的主要秘诀是推理每一步,关于轴指向的位置,以及您在对象的哪个点应用变换。纸和铅笔或反复试验,不管用什么都是好的。

下面是我放置三角形的方法:

  • 将 css-transform 放在所有三角形底部的中间
  • 围绕 Y 轴旋转 90° 的倍数,以将每个三角形定向到金字塔的不同面(分别为 0、90、180、270)
  • 沿 Z 平移 1/2 Base 以获得正确的位置
  • 沿 X 轴旋转所需角度​​ (90°-α) 以使它们在顶点处相遇。

由于第一次旋转,最后两个相同的步骤将在所有三角形上执行您想要的操作。

对于base,比较简单,可以保持默认的css-transform

  • 沿 X 轴旋转 90°(使其在垂直于屏幕的平面上“变平”)
  • 将其沿 Z 移动 (Apothem - 1/2 Base) 以与三角形的底对齐

下面是 α = 45° 时的样子,如果不想剧透,请不要打开 sn-p。

#pyramid {
  perspective: 400px;
  padding: 50px 0 0 200px;
}
#pyramid div:not(.base) {
  position: absolute;
  border-left: 100px solid transparent;   /* 1/2 Base */
  border-right: 100px solid transparent;   /* 1/2 Base */
  border-bottom: 141px solid;  /* Apothem */
  transform-origin: 100px 141px 0; /* bottom of trangle (1/2 Base, Apothem) */
  opacity: .5;
}
.base {
  position: absolute;
  width: 200px;
  height: 200px;
  background-color: #2f2f2f;
  /* transform by default from middle (100px, 100px)
     move by Apothem - 1/2 Base = 41px */
  transform: rotateX(90deg) translate3d(0px, 0px, -41px);
  opacity: .5;
}
#pyramid div:nth-child(2) {
  border-bottom-color: #e04545;
  transform: rotateY(0deg) translate3d(0px, 0px, 100px) rotateX(45deg);
}
#pyramid div:nth-child(3) {
  border-bottom-color: #ccaf5a;
  transform: rotateY(90deg) translate3d(0px, 0px, 100px) rotateX(45deg);
}
#pyramid div:nth-child(4) {
  transform: rotateY(180deg) translate3d(0px, 0px, 100px) rotateX(45deg);
}
#pyramid div:nth-child(5) {
  border-bottom-color: #4ccfc7;
  transform: rotateY(270deg) translate3d(0px, 0px, 100px) rotateX(45deg);
}
<!doctype html>
<html>
<head><title>Pyramid</title></head>
<body>
<div class="pyramid-container">
  <div id="pyramid">
    <div class="base"></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
  </div>  
  </div>
</body>
</html>

【讨论】:

  • 非常感谢您的回答。我不明白的一件事是上面关于 cos 的一点。我知道要找到高度,您将使用 cos(alpha) = 相反/相邻,但在下一句中您开始提到 cos(alpha) = 1。我仍然对 apothem 计算感到有些困惑,或者您能否提供一个请给个链接?
  • tan(alpha) = 相反/相邻; cos(alpha) = 相邻 / 斜边。在您最初的 jsbin 中,您有相邻 = 1/2 Base = 100px 和 Apothem = triangle height = hypothenuse = 100px
  • 坐,我欠你一杯啤酒
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多