将旋转的矩形缩放到覆盖其容器所需的最小尺寸

问题描述 投票:0回答:2

我有一个矩形框架,以及第二个可以旋转的矩形。我想确定需要对旋转矩形应用什么最小比例才能完全覆盖固定框架。

我已经看到了类似问题的解决方案,这些解决方案解决了最大比例以包含父级中的旋转矩形,但我无法破译它们的功能,以便弄清楚修改它们需要进行哪些更改我覆盖它的用例。

此示例展示了如何包含旋转矩形,其中要应用的比例计算为从角到角的当前距离除以从角到角的原始距离。反转它确实达到了我想要的效果,但只有在子级和父级大小相同的情况下才有效。您可以在 this codepen 中看到它的功能,但是如果您更改

#rect1
的纵横比,它就不再起作用。

这个第二个例子适用于任何大小的2个矩形(这里是一个codepen链接),但是,我无法破译它如何发挥作用足以使矩形覆盖框架,而不是包含在框架内.

有人能帮忙计算一下实现这一目标需要什么吗?

javascript jquery css math trigonometry
2个回答
0
投票

如果你想一想,旋转正方形的宽度应该是参考正方形的斜边。然后要得到比例,只需除以旋转正方形的宽度即可。

不确定您是否需要像示例那样在 javascript 中使用此功能?您只需使用 css 即可处理大部分内容。你唯一需要 javascript 的就是动态更新比例 css 变量,因为 css 不支持这个,但是......

let rect = {
      ref: document.querySelector('.rect.ref'),
      rot: document.querySelector('.rect.rot'),
      get_scale: () =>
        Math.hypot(rect.ref.clientHeight, rect.ref.clientWidth) / rect.rot.clientWidth,
      set_scale: () => {
        document.getElementById('scale').innerHTML =
          `:root { --rotate-scale: ${rect.get_scale()}; }`;
      }
  };

//this is just to make it interactive
document.querySelectorAll('input').forEach((input, index, inputs) => {
  input.addEventListener('input', function() {
    rect.ref.style.aspectRatio = ([...inputs].map((i) => i.value).join(' / '));
    rect.set_scale();
  });
});
@keyframes rotate {
  0% { transform: rotate(0deg) scale(var(--rotate-scale)) }
  100% { transform: rotate(360deg) scale(var(--rotate-scale)) }
}

body {
  align-items: center;
  display: flex;
  height: 100vh;
  justify-content: center; }
  
.aspect {
  display: grid;
  left: 0;
  position: fixed;
  top: 0;
  z-index: 1; }

.rect {
  border: 1px solid black;
  box-sizing: border-box;
  position: absolute;
  width: 100px; }

.rect.ref {
  aspect-ratio: 1 / 1; }

.rect.rot {
  animation: rotate 3s linear infinite;
  aspect-ratio: 1 / 1;
  background-color: #ff000050;
  border-color: #ff000050; }
<html>
  <head>
    <style id="scale">
      <!-- start with the hypotenuse of the unit square, aka sqrt(2) -->
      :root { --rotate-scale: 1.412; }
    </style>
  </head>
  <body>
    <div class="aspect">
      <input type="range" min="1" max="10" value="1">
      <input type="range" min="1" max="10" value="1">
    </div>
    
    <div class="rect ref"></div>
    <div class="rect rot"></div>
  </body>
</html>


0
投票

使用您链接到的codepen中的代码库,并使用简单的三角学,接触最小尺寸的外部矩形的内部矩形的对角线,可用于确定该矩形的边之一,并据此确定其与原始尺寸的比例版本。用代码比用文字看得更清楚:

const cont= document.querySelector('#rect2');
const rot= document.querySelector('#rect1');
const hRot = rot.offsetHeight, h = cont.offsetHeight;
const wRot = rot.offsetWidth, w = cont.offsetWidth;

let t=0; 
const anim= setInterval(rotate, 10);
function rotate(){
    rot.style.transform = "rotate(-" + t + "deg)";
    update(t);
    t += 0.1;
    t = t % 360;
}

function update(T){
  T = T % 180; 
  T = T > 90 ? 180 - T : T;
  const phi = degToRad(T),
     sin_phi = Math.sin(phi),
     cos_phi = Math.cos(phi),
     ratio1 = (w * cos_phi + h * sin_phi) / wRot,
     ratio2 = (w * sin_phi + h * cos_phi) / hRot,
     ratio = Math.max(ratio1, ratio2);
  
  rot.style.transform += " scale(" + ratio + ")";
}

function degToRad(angle){
 return angle * Math.PI / 180;
}
body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
#rect1 {
  position: absolute;
  width: 100px;
  aspect-ratio: 2/1;
  background: red;
  opacity: 0.5;
/*   transform: rotate(50deg); */
}
#rect2 {
  position: absolute;
  width: 200px;
  aspect-ratio: 2/1;
  border: 1px solid black;
  opacity: 0.5;
}
<div id="rect1"></div>
<div id="rect2"></div>

与原始消息中的fiddle相同;它允许人们调整两个矩形的大小和纵横比。

© www.soinside.com 2019 - 2024. All rights reserved.