Вот иллюстрация, чтобы лучше показать проблему и расчет, который мы должны сделать:
.box {
margin: 50px;
width: 200px;
height: 100px;
outline: 2px solid;
box-sizing: border-box;
}
.rect {
width: 100%;
height: 100%;
border: 1px solid green;
box-sizing: border-box;
transform-origin: bottom left;
background: linear-gradient(to bottom right, transparent 49%, red 49%, red 52%, transparent 52%);
animation: change 5s linear infinite alternate;
}
@keyframes change {
from {
transform: rotate(0deg);
}
to {
transform: rotate(53deg);
}
}
<div class="box">
<div class="rect">
</div>
</div>
Как видите, у нас есть диагональная линия (красная), которую нам нужно уменьшить, чтобы избежать переполнения.
На рисунке ниже у нас есть угол поворота (синим цветом) и угол фиолетового цвета, основанный на размере прямоугольника. Отсюда получаем следующую формулу:
cos(PurpleAngle) = width/X
cos(PurpleAngle - BlueAngle) = width/X1
, где X1
- ширина, необходимая для нашей диагонали (ограничена желтым крестом), а X
- ширина диагонали (полная красная линия).
Затем мы можем написать это:
X/X1 = cos(PurpleAngle - BlueAngle)/cos(PurpleAngle)
тогда
X/X1 = (cos(PurpleAngle)*cos(BlueAngle) + sin(PurpleAngle)*sin(BlueAngle))/cos(PurpleAngle)
упрощаем до
X/X1 = cos(BlueAngle) + tan(PurpleAngle)*sin(BlueAngle)
Мы знаем BlueAngle
, который является нашим углом поворота, и мы можем легко найти tan(PurpleAngle)
, который просто Height/Width
. Да, нам нужно знать ширину и высоту или хотя бы соотношение между ними. В моем случае я использовал соотношение 0.5
, поэтому будет иметь:
X/X1 = cos(BlueAngle) + 0.5*sin(BlueAngle)
Теперь мы можем видеть это как еще один поворот по оси Y, где у нас будет cos(B) = X1/X
.
* * Пример тысяча сорок-одиной: * +1042 *
.box {
margin: 50px;
width: 200px;
height: 100px;
outline: 2px solid;
box-sizing: border-box;
}
.rect {
width: 100%;
height: 100%;
border: 1px solid green;
box-sizing: border-box;
transform:rotate(20deg) rotateY(25.84deg);
background: linear-gradient(to bottom right, transparent 49%, red 49%, red 52%, transparent 52%);
animation: change 5s linear infinite alternate;
}
<div class="box">
<div class="rect">
</div>
</div>
Или мы также можем видеть это как масштабное преобразование с коэффициентом, равным X1/X
:
Пример: * * тысяча пятьдесят-три
.box {
margin: 50px;
width: 200px;
height: 100px;
outline: 2px solid;
box-sizing: border-box;
}
.rect {
width: 100%;
height: 100%;
border: 1px solid green;
box-sizing: border-box;
transform:rotate(20deg) scale(0.9);
background: linear-gradient(to bottom right, transparent 49%, red 49%, red 52%, transparent 52%);
animation: change 5s linear infinite alternate;
}
<div class="box">
<div class="rect">
</div>
</div>
Итак, все, что вам нужно сделать, это узнать соотношение, а затем угол поворота, используя формулу, чтобы найти значение шкалы или значение поворота.
Больше примеров:
.box {
margin: 20px;
width: 150px;
height: 75px;
display:inline-block;
vertical-align:top;
outline: 2px solid;
box-sizing: border-box;
}
.rect {
width: 100%;
height: 100%;
border: 1px solid green;
box-sizing: border-box;
}
<!-- 1/(cos(20deg) + 0.5*sin(20deg)) -->
<div class="box">
<div class="rect" style="
transform:rotate(20deg) scale(0.9);">
</div>
</div>
<!-- 1/(cos(45deg) + 1*sin(45deg)) -->
<div class="box" style="height:150px">
<div class="rect" style="
transform:rotate(45deg) scale(0.707);">
</div>
</div>
<!-- 1/(cos(5deg) + 0.333*sin(5deg)) -->
<div class="box" style="height:50px">
<div class="rect" style="
transform:rotate(5deg) scale(0.972);">
</div>
</div>
<!-- 1/(cos(15deg) + 2*sin(15deg)) -->
<div class="box" style="height:300px;">
<div class="rect" style="
transform:rotate(15deg) scale(0.674);">
</div>
</div>
Используя SASS, вы можете рассмотреть эту ссылку (https://unindented.org/articles/trigonometry-in-sass/), где вы можете найти определение cos()
sin()
, тогда вы просто сделаете:
@function scale-factor($angle, $ratio) {
@return 1/(cos($angle) + $ratio*sin($angle));
}
div {
transform:rotate(15deg) scale(scale-factor(15deg,2));
}
И вы получите это:
div {
transform: rotate(15deg) scale(0.6740525224);
}
Для решения CSS мы также можем положиться на calc()
, чтобы упростить вычисления, выполнив scale(calc(1 / (cos(a) + r*sin(a)))
, где нам нужно только вычислить cos()
и sin()