【问题标题】:CSS: Calculate the overflow of two overlapping rectangles after one has been rotatedCSS:计算两个重叠矩形在旋转后的溢出
【发布时间】:2019-08-13 06:44:24
【问题描述】:

我知道一个奇怪的问题,但我想知道在第一个矩形使用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 的 width(由 :after 构建的那个)是 X 以适应父元素。像width: calc(100% - overflow) 这样的东西。

这可能吗,还是我需要解决类似width: 98% 的问题?

【问题讨论】:

  • 很不清楚你想做什么。如果它们具有相同的宽高,它们将“合身”。请详细说明您想要实现的目标
  • 好的,所以我要画矩形。矩形 1 有一个基于它的内容的 width。我在 CSS 中用:after 创建了第二个矩形(矩形2)。在 Given 示例中,此矩形的宽度为 100%。现在我希望矩形 2 的宽度类似于 width: calc(100% - overlapping space of the rectangle);
  • 嗯,你在你的问题中说Now I want the width of rectangle 2 (the one built by :after) to still be 100% of the parent width. :) 那是令人困惑的。
  • 感谢您的提示,我已经编辑了这部分问题。 :)
  • 嗯,溢出我认为它太动态了,无法用 CSS 计算。你可以做一个“安全”的假设,并做出类似:jsfiddle.net/bcqw0y58/3 这在很大程度上取决于轮换。多少度。

标签: html css sass css-transforms css-calc


【解决方案1】:

为了更好地展示问题和我们需要做的计算,这里有一个插图:

.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,您可以考虑这个链接 (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()

【讨论】:

  • 这就是我所说的高质量答案
猜你喜欢
  • 2023-03-18
  • 2015-01-25
  • 1970-01-01
  • 2010-11-29
  • 2011-08-12
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
相关资源
最近更新 更多