CSS:计算两个重叠矩形旋转后的溢出
CSS: Calculate the overflow of two overlapping rectangles after one has been rotated
我知道这是一个奇怪的问题,但我想知道是否可以计算出在第一个矩形 transform: rotate
旋转后一个矩形需要完全适合另一个矩形的宽度。这是我想说的图片:
理想情况下,我希望它是动态的,因此它不依赖于第一个矩形的实际情况。
我正在使用 SCSS,这是我目前得到的结果:
.background-box {
background: black;
padding: rem(30px 40px);
position: relative;
width: auto;
&:after {
content: "";
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
@include transform(rotate(5deg));
border: rem(2px) solid $primary;
background: transparent;
z-index: -1;
}
}
HTML 看起来像这样:
<div class="background-box">
//CONTENT
</div>
现在我希望矩形 2(由 :after
构建的矩形)的 width
为 X 以适合父元素。像 width: calc(100% - overflow)
这样的东西。
这可能吗,还是我需要解决 width: 98%
之类的问题?
这里有一个插图可以更好地展示问题和我们需要做的计算:
.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
。
示例:
.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 你可以考虑这个 link (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()
我知道这是一个奇怪的问题,但我想知道是否可以计算出在第一个矩形 transform: rotate
旋转后一个矩形需要完全适合另一个矩形的宽度。这是我想说的图片:
理想情况下,我希望它是动态的,因此它不依赖于第一个矩形的实际情况。
我正在使用 SCSS,这是我目前得到的结果:
.background-box {
background: black;
padding: rem(30px 40px);
position: relative;
width: auto;
&:after {
content: "";
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
@include transform(rotate(5deg));
border: rem(2px) solid $primary;
background: transparent;
z-index: -1;
}
}
HTML 看起来像这样:
<div class="background-box">
//CONTENT
</div>
现在我希望矩形 2(由 :after
构建的矩形)的 width
为 X 以适合父元素。像 width: calc(100% - overflow)
这样的东西。
这可能吗,还是我需要解决 width: 98%
之类的问题?
这里有一个插图可以更好地展示问题和我们需要做的计算:
.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
。
示例:
.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 你可以考虑这个 link (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()