Создать четырехугольник с определенной степенью - PullRequest
3 голосов
/ 13 марта 2019

Как я могу создать четырехугольник с помощью css, когда я знаю, какой градус имеет каждый угол.

Я уже пытался воссоздать четырехугольник с преобразованием и перекосом.

Однако это не очень хорошо работает.

Это то, что я пытаюсь архивировать.

enter image description here

Точные требования:

Div с этим цветом фона. На изображении только строительные линии. Это должен быть сплошной четырехугольник с этими углами.

Это была моя первая идея:

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

Ответы [ 2 ]

2 голосов
/ 13 марта 2019

Я хотел бы рассмотреть несколько фонов для достижения этой цели, где мне просто нужно найти ширину / высоту элемента. На основании вашей иллюстрации мы имеем это:

enter image description here

Отсюда можно получить следующую формулу:

tan(alpha) = W/H

и

tan(beta/2) = H/W

Нам нужно использовать только один из них, и вы заметите, что не существует логичного решения, так как вам просто нужно сохранить соотношение между H и W, а ширина нашего элемента будет просто равна 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 (квадрат), затем мы вращаемся, как показано ниже:

enter image description here

Это вид сбоку. Зеленый - это наш повернутый элемент, а красный - начальный. Понятно, что мы увидим высоту H1 после выполнения поворота, и у нас будет эта формула:

cos(angle) = H1/H

И у нас уже есть tan(alpha)=W/H1, поэтому у нас будет

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

и H=W, так как изначально мы определили квадрат, поэтому у нас будет 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>

Мы также можем применить ту же логику, используя rotateY(), чтобы обновить ширину в ситуации, когда у вас будет бета больше 90deg и альфа меньше 45deg. В этом случае у нас будет W < H, а rotateX() нам не поможет.

Математика может легко это подтвердить. когда alpha меньше, чем 45deg tan(alpha) будет меньше, чем 1, таким образом, 1/tan(alpha) будет больше, чем 1, а cos определяется только между [-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>
2 голосов
/ 13 марта 2019

Вы можете сделать это по-разному.Поскольку вы пытаетесь использовать значение в градусах, то здесь я могу привести пример: сначала вы можете взять четыре строки для вашего прямоугольника и повернуть их, как вы хотите, со значением в градусах.Вот что я имею в виду:

<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; }

Вот предварительный просмотр

...