Я хотел бы рассмотреть несколько фонов для достижения этой цели, где мне просто нужно найти ширину / высоту элемента. На основании вашей иллюстрации мы имеем это:
Отсюда можно получить следующую формулу:
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
(квадрат), затем мы вращаемся, как показано ниже:
Это вид сбоку. Зеленый - это наш повернутый элемент, а красный - начальный. Понятно, что мы увидим высоту 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>