Create quadrilateral with specific degree

China☆狼群 提交于 2019-12-12 16:26:42

问题


How can I create a quadrilateral with css, when I know which degree each corner has.

I already tried to recreate a quadrilateral I have with transform and skew.

However, this does not work really well.

This is what I try to archive.

The exact requirements are:

A div with this as background in one color. On the image are just construction lines. It should be a solid quadrilateral with these angles.

This was my first idea:

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

回答1:


I would consider multiple background to achieve this where I simply need to find the width/height of the element. Based on your illustration we have this:

From this we can have the following formula:

tan(alpha) = W/H

and

tan(beta/2) = H/W

We only need to use one of them and you will notice that there isn't one solution which is logical as you simply need to keep a ratio between H and W and the width of our element will simply be 2*W and its height 2*H.

Since H/W is also the same as 2*H/2*W we can simply consider that 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>

You can adjust the gradient if you want only borders:

.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>

Using transform the idea is to rely on rotateX() in order to visually decrease the height to keep the formula defined previously. So we start by having Width=height (a square) then we rotate like below:

This is a view from the side. The green is our rotated element and the red the initial one. It's clear that we will see the height H1 after performing the rotation and we have this formula:

cos(angle) = H1/H

And we aleardy have tan(alpha)=W/H1 so we will have

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

and H=W since we defined a square initially so we will have cos(angle) = 1/tan(alpha) --> 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>

We can also apply the same logic using rotateY() to update the width in the situation where you will have beta bigger than 90deg and alpha smaller than 45deg. In this case we will have W < H and the rotateX() won't help us.

The math can easily confirm this. when alpha is smaller than 45deg tan(alpha) will be smaller than 1 thus 1/tan(alpha) will bigger than 1 and cos is only defined between [-1 1] so there is no angle we can use with rotateX()

Here is an animation to illustrate:

.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>



回答2:


In various way you can do it. Since you're trying to use degree value so here I can give you an example: first of you can take four lines for your rectangle and rotate them as you want with degree value. Here is what I mean:

<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



来源:https://stackoverflow.com/questions/55148401/create-quadrilateral-with-specific-degree

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!