【问题标题】:How to create quadrilateral (rhombus shape) with specific degree?如何创建具有特定度数的四边形(菱形)?
【发布时间】:2019-08-04 12:20:53
【问题描述】:

当我知道每个角的度数时,如何使用 css 创建一个四边形。

我已经尝试通过变换和倾斜重新创建一个四边形。

但是,这并不能很好地工作。

这是我尝试归档的内容。

具体要求是:

以一种颜色作为背景的 div。图像上只是构造线。它应该是具有这些角度的实心四边形。

这是我的第一个想法:

transform: rotate(-45deg) skew(27.5deg, 62.5deg)
transform-origin: top center;

【问题讨论】:

  • 上图似乎不是正方形。正方形应该有 4 个相等的边,所有边的长度都相等,每个角都是 90 度。
  • 对不起。 Square是“Viereck”的翻译。我不是以英语为母语的人。所以也许我的意思是“四边形”
  • 我可以看到左右角各53度。底角是多少?我问是因为它似乎被覆盖且不清楚。是250度吗?
  • 62.5。当然总和是 125。它们不是 100% 准确的,因为我是从图像中提取它们的。当然所有角度的总和(如果将四边形分成4个三角形)需要等于180。26 + 90 + 62.5 =~ 180
  • 我完全忘记了,英文的标点符号不同。用更易读的数字更新了图像。

标签: css css-transforms css-shapes


【解决方案1】:

我会考虑使用多个背景来实现这一点,我只需要找到元素的宽度/高度。根据您的说明,我们有:

由此我们可以得出以下公式:

tan(alpha) = W/H

tan(beta/2) = H/W

我们只需要使用其中一个,您会注意到没有一种解决方案是合乎逻辑的,因为您只需要保持HW 之间的比率,我们元素的宽度就是2*W 及其高度2*H

由于H/W 也与2*H/2*W 相同,我们可以简单地认为width = tan(alpha)*height

.box {
  height:var(--h);
  width:calc(1.92098213 * var(--h)); /* tan(62.5)xH */
  background:
   linear-gradient(to bottom right,transparent 49%,red 50%) top left,
   linear-gradient(to top    right,transparent 49%,red 50%) bottom left,
   linear-gradient(to bottom left ,transparent 49%,red 50%) top right,
   linear-gradient(to top    left ,transparent 49%,red 50%) bottom right;
  background-size:50% 50%;
  background-repeat:no-repeat;
}
<div class="box" style="--h:50px;"></div>

<div class="box" style="--h:100px;"></div>

<div class="box" style="--h:200px;"></div>

如果你只想要边框,你可以调整渐变:

.box {
  height:var(--h);
  width:calc(1.92098213 * var(--h)); /* tan(62.5)xH */
  background:
   linear-gradient(to bottom right,transparent 49%,red 50%,transparent calc(50% + 2px)) top left,
   linear-gradient(to top    right,transparent 49%,red 50%,transparent calc(50% + 2px)) bottom left,
   linear-gradient(to bottom left ,transparent 49%,red 50%,transparent calc(50% + 2px)) top right,
   linear-gradient(to top    left ,transparent 49%,red 50%,transparent calc(50% + 2px))  bottom right;
  background-size:50% 50%;
  background-repeat:no-repeat;
}
<div class="box" style="--h:50px;"></div>

<div class="box" style="--h:100px;"></div>

<div class="box" style="--h:200px;"></div>

使用变换的想法是依靠rotateX() 以在视觉上降低高度以保持先前定义的公式。所以我们从Width=height(一个正方形)开始,然后我们像下面这样旋转:

这是侧视图。绿色是我们的旋转元素,红色是初始元素。很明显,执行旋转后我们会看到高度H1,我们有这个公式:

cos(angle) = H1/H

我们已经拥有tan(alpha)=W/H1,所以我们将拥有

cos(angle) = W/(H*tan(alpha)) 

还有H=W,因为我们最初定义了一个正方形,所以我们将拥有cos(angle) = 1/tan(alpha) --&gt; angle = cos-1(1/tan(alpha))

.box {
  width:150px;
  height:150px;
  background:red;
  margin:50px;
  transform:rotateX(58.63017731deg) rotate(45deg); /* cos-1(0.52056)*/
}
<div class="box">

</div>

我们也可以使用rotateY() 应用相同的逻辑来更新宽度,在这种情况下您的 beta 将大于 90deg 并且 alpha 小于 45deg。在这种情况下,我们将拥有W &lt; H,而rotateX() 将无济于事。

数学很容易证实这一点。当alpha 小于45deg tan(alpha) 将小于1 因此1/tan(alpha) 将大于1cos 仅在[-1 1] 之间定义,因此我们无法使用任何角度rotateX()

这里有一个动画来说明:

.box {
  width:100px;
  height:100px;
  display:inline-block;
  background:red;
  margin:50px;
  animation:change 5s linear infinite alternate;
}
.alt {
  animation:change-alt 5s linear infinite alternate;
}

@keyframes change {
  from{transform:rotateX(0) rotate(45deg)}
  to{  transform:rotateX(90deg) rotate(45deg)}
}
@keyframes change-alt {
  from{transform:rotateY(0) rotate(45deg)}
  to{  transform:rotateY(90deg) rotate(45deg)}
}
<div class="box">

</div>

<div class="box alt">

</div>

【讨论】:

  • 谢谢!这几乎是完美的。至少它完美地回答了这个问题。但是,有没有办法使用border-radius或者模仿呢?
  • @Noim 我正在添加另一种方式 ;) 给我 5 分钟
  • @Noim 检查更新,使用新方法可以轻松添加半径;)
【解决方案2】:

您可以通过多种方式做到这一点。由于您正在尝试使用度数值,所以在这里我可以给您举个例子:首先,您可以为矩形取四条线,并根据需要使用度数值旋转它们。这就是我的意思:

<div class="top_line"></div>
<div class="right_line"></div>
<div class="bottom_line"></div>
<div class="left_line"></div>

CSS

.top_line { height: 170px; border-right: 1px solid yellow; transform: rotate(50deg);
  position: absolute; top: 140px; left: 400px; transform-origin: 0% 130%; }
.right_line {height: 140px; border-right: 1px solid red; transform: rotate(130deg);
  position: absolute; top: 140px; left: 500px; transform-origin: 0% 50%; }
.bottom_line { height: 140px; border-right: 1px solid green; transform: rotate(130deg);
  position: absolute; top: 140px; left: 400px; transform-origin: -1800% 80%; }
.left_line { height: 140px; border-right: 1px solid blue; transform: rotate(50deg);
  position: absolute; top: 140px; left: 400px; }

Here is the live preview

【讨论】:

  • 谢谢。我了解您所做的以及如何做到的,但是它并不真正符合我的目标(至少我认为)。我尝试用这种形状重新创建一个实体表面,而不是图像中的构造线。
猜你喜欢
  • 2014-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 1970-01-01
  • 2022-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多