【问题标题】:How to make a tetrahedron?如何制作四面体?
【发布时间】:2016-01-24 18:20:07
【问题描述】:

我正在尝试制作一个 CSS 四面体,因此我通过做一些 CSS3 三角形并使用透视属性激活 3D 转换来解决这个问题。

但是我有一些问题需要考虑所有的转换,这是我的一些代码:

.navbar-brand-logo {
  width: 64px;
  height: 64px;
  transform-style: preserve-3d;
  perspective: 600px;
  position: relative;
}
.face {
  width: 0;
  height: 0;
  position: absolute;
  border-style: solid;
  border-width: 64px 32px 0 32px;
  transform-origin: 0 0;
  border-color: transparent transparent transparent rgba(50, 50, 50, 0.6);
}
.logo-base-left {
  transform: rotateX(180deg) translateY(-64px);
}
.logo-base-right {
  transform: rotateY(180deg) rotateX(180deg) translateY(-64px);
}
.logo-up {
  border-color: transparent transparent transparent rgba(50, 50, 50, 0.8);
  transform: rotateY(180deg) scaleY(0.5) translateY(-64px);
}
.logo-down-up {
  border-color: transparent transparent transparent rgba(50, 50, 50, 0.9);
  border-width: 64px 0 0px 4px;
  transform: scaleX(128px) translateZ(0px);
}
<section class="navbar-brand-logo">
  <figure class="face logo-base-left"></figure>
  <figure class="face logo-base-right"></figure>
  <figure class="face logo-up"></figure>
  <figure class="face logo-down-up"></figure>
</section>

我无法想象如何制作另外两张脸(左上一张和右一张)。

这是一个CodePen,它说明了当前的尝试:

此外,使用 CSS3 四面体作为徽标是个好主意吗? 如果是 SVG 会更好吗?

由于浏览器支持,WebGL / Canvas 是一个禁忌。

【问题讨论】:

  • 您确定浏览器支持吗?请参阅stemkoski.github.io/Three.js/Shapes.html:它适用于大多数现代浏览器
  • @vals:说实话,我觉得 WebGL 最大的问题是 Linux 上的视频驱动程序。我问自己 WebGL 与 3D CSS 之间的性能。手机呢?
  • 未来会有 SVG 3D,但目前只有 2D 支持 svg。

标签: css svg css-shapes css-transforms


【解决方案1】:

以下是描述制作响应式四面体的方法的几个步骤:demo - responsive tetrahedron

link to animation

第 1 步的面孔:

tetrahedron 有 4 个三角形面。每张脸都是一个equilateral triangle。 在下面的示例中,我使用了clip-path property 来制作 4 个等边三角形:

.tetra{
  position:relative;
  width:20%; 
  padding-bottom:17.32%; /* height of equilateral triangle = sin60° * width */
  margin:0 auto;
}

.tetra div{
  position:absolute;
  top:0;left:0;
  width:100%; height:100%;
  -webkit-clip-path:polygon(50% 0, 100% 100%, 0% 100%);
  clip-path:polygon(50% 0, 100% 100%, 0% 100%);
  background:teal;
}

.tetra .face2{
  transform-origin:0% 100%;
  transform:rotate(-60deg);
  background:gold;
}
.tetra .face3{
  transform-origin:100% 100%;
  transform:rotate(60deg);
  background:darkorange;
}
.tetra .face4{
  transform-origin:50% 100%;
  transform:rotate(180deg);
  background:pink;
}
<div class="tetra">
  <div class="face1"></div>
  <div class="face2"></div>
  <div class="face3"></div>
  <div class="face4"></div>
</div>

第 2 步制作 3d

为此,我们使用perspectivetransform-style 在3d 环境中分别旋转每个面:

body{
  perspective:9000px;
}
.tetra{
  position:relative;
  width:20%; 
  padding-bottom:17.32%; /* height of equilateral triangle = sin60° * width */
  margin:0 auto;  
  transform-style:preserve-3d;
}

.tetra div{
  position:absolute;
  top:0;left:0;
  width:100%; height:100%;
  -webkit-clip-path:polygon(50% 0, 100% 100%, 0% 100%);
  clip-path:polygon(50% 0, 100% 100%, 0% 100%);
  background:teal;  
  transform-style:preserve-3d;
}

/* Rotation of –109.5° is angle(C, M[AB], D), per http://www.f-lohmueller.de/pov_tut/geo/geom_200e.htm, 180° – atan(2 * sqrt(2)) ≈ 109.5° */
.tetra .face2{
  transform-origin:0% 100%;
  transform:rotate(-60deg) rotatex(-109.5deg);
  background:gold;
}
.tetra .face3{
  transform-origin:100% 100%;
  transform:rotate(60deg) rotatex(-109.5deg);
  background:darkorange;
}
.tetra .face4{
  transform-origin:50% 100%;
  transform:rotate(180deg) rotatex(-109.5deg);
  background:pink;
}
<div class="tetra">
  <div class="face1"></div>
  <div class="face2"></div>
  <div class="face3"></div>
  <div class="face4"></div>
</div>

此时,您有一个四面体,但您只能看到 3 个面,因此可以看到整个 3d 形状:

第 3 步让它旋转!

顶看整个四面体,你需要用过渡或关键帧动画来旋转它:

body{
  perspective:9000px;
  padding-top:10%;
}
.tetra{
  position:relative;
  width:20%; 
  padding-bottom:17.32%; /* height of equilateral triangle = sin60° * width */
  margin:0 auto;  
  transform-style:preserve-3d;  
  transform:rotatex(90deg) rotateY(0deg) rotatez(0deg);
  animation: rotate 10s linear infinite;
}

.tetra div{
  position:absolute;
  top:0;left:0;
  width:100%; height:100%;
  -webkit-clip-path:polygon(50% 0, 100% 100%, 0% 100%);
  clip-path:polygon(50% 0, 100% 100%, 0% 100%);
  background:teal;  
  transform-style:preserve-3d;
}

/* Rotation of –109.5° is angle(C, M[AB], D), per http://www.f-lohmueller.de/pov_tut/geo/geom_200e.htm, 180° – atan(2 * sqrt(2)) ≈ 109.5° */
.tetra .face2{
  transform-origin:0% 100%;
  transform:rotate(-60deg) rotatex(-109.5deg);
  background:gold;
}
.tetra .face3{
  transform-origin:100% 100%;
  transform:rotate(60deg) rotatex(-109.5deg);
  background:darkorange;
}
.tetra .face4{
  transform-origin:50% 100%;
  transform:rotate(180deg) rotatex(-109.5deg);
  background:pink;
}
@keyframes rotate{
  50%{transform:rotatex(100deg) rotateY(10deg) rotatez(180deg);}
  100%{transform:rotatex(90deg) rotateY(0deg) rotatez(360deg);}
}
<div class="tetra">
  <div class="face1"></div>
  <div class="face2"></div>
  <div class="face3"></div>
  <div class="face4"></div>
</div>

请注意,这使用了并非所有浏览器都支持的属性,尤其是只有 chrome 支持的剪辑路径。此属性用于制作等边三角形,您可以使用其他方法(see here)。

有关浏览器支持和供应商前缀,另请参阅 canIuse for:

【讨论】:

  • 为什么要旋转-109.5度,你从哪里得到这个数字?
  • @2540625 这是角度(C,MAB,D) 在这里看到:f-lohmueller.de/pov_tut/geo/geom_200e.htm 180 - atan(2*sqrt(2)) ~= 109.5 degrees
  • 谢谢。我已经编辑了您的答案以添加该解释。
【解决方案2】:

如果您想为徽标设置动画(一次,悬停,没关系),那么使用 3D CSS 可能是个好主意。

使用 SVG,您将获得更好的浏览器支持、更快的渲染和更轻松的形状控制,因此如果您不为徽标制作动画,我建议您使用 SVG。

要在 3D 中构建四面体的形状,请查看 Ana Tudor 的 codepen,这只是她制作的众多四面体示例之一:http://codepen.io/thebabydino/pen/vFrHx - 您可以在这支笔中使用动画 rot 来了解一下如何旋转/动画它。

【讨论】:

  • 不确定最初的想法是否来自 Lea,但那支笔 (thebabydino) 是 Ana 的。
  • 是的,哈利说得对。钢笔是 Ana Tudor (thebabydino) 设计的
  • 那个CodePen的结果很漂亮,但是它的代码需要cmets。为什么使用 scaleX(1.155)?为什么旋转X(19.47度)?为什么要翻译Z(4.6188em)?
【解决方案3】:

在有机分子中,四面体通常是相关的螺旋,例如: Boerdijk-Coxeter 螺旋。所以写代码来显示这个螺旋线会很好。 这是螺旋的 javascript:

var s set equal to the sides of the square canvas
var a=s/6, b=s/9;
c.beginPath();
for (var i=0; i<2*Math.PI; i+=0.01){
  x=s/4+a*Math.cos(i)-b*Math.sin(i);
  y=3*s/4+a*Math.cos(i)+b*Math.sin(i);
  if(i==0) {c.moveTo(x,y);} else {c.lineTo(x,y);}
}
c.lineWidth=1;
c.strokeStyle="#0f6";
c.stroke();

【讨论】:

  • 欢迎来到 StackOverflow!虽然您的贡献非常有趣,但这实际上并不是对最初提出的问题的回答。请访问帮助中心以获取有关如何回答问题的提示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-17
  • 2010-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
相关资源
最近更新 更多