滚动条与变换对象的实际边界不匹配

时间:2017-08-23 19:49:49

标签: html css css3 css-transforms

我尝试使用transform: rotate(45deg);旋转html元素。这确实有效,但滚动条与旋转元素的视觉边界不匹配。

上下文是我想创建一个pdf-viewer应用程序,用户也可以在其中旋转文件以获得更好的可读性。但是,他不可能滚动整个文件,因为滚动条不够长。

this fiddle为例。滚动条太短,因此您无法滚动到每个角落。

如何解决此问题,以便您可以滚动整个元素?

jQuery解决方案没问题。我在Chrome v.60

中对此进行了测试

2 个答案:

答案 0 :(得分:1)

当html转换发生时,它独立于其他元素工作。这意味着转换后的元素不会移动邻居或调整其父级的大小。

您可以为图片的父级使用预定的填充。或者您可以在转换期间更改它,但在这种情况下,您需要处理窗口滚动位置。

90度旋转元素所需的填充取决于要旋转的图像的较大尺寸等于:

(biggerDimension - lesserDimension) / 2

因此,你的jQuery函数为父代获得正确的填充将类似于这个抽象的:

var $img       = $('img'),
     imgWidth  = $img.width(),
     imgHeight = $img.height();

if (imgWidth > imgHeight) {
  var parentPadding = (imgWidth - imgHeight) / 2;
} else {
  var parentPadding = (imgHeight - imgWidth) / 2;
}

如果您的图像是正方形,则不需要填充(旋转90度)。

但是如果你想找到所需的最大填充(对于45度,135度等旋转),公式会有点复杂。 例如,如果最大尺寸是宽度,并且您想要设置padding-top

sqrt(imgWidth^2 + imgHeight^2) / 2 - imgHeight / 2

半个对角线减去半个高度。您可以更改高度较大的情况和其他角落的公式。

当然,如果img是响应式的,则需要在调整大小时调用该函数。

答案 1 :(得分:1)

因此,我认为我们需要克服的两个主要问题是:

  1. 图片大于容器
  2. 即使图像不大于容器,一旦旋转,它就会变大,因为相对角之间的长度将长于图像任何一侧的长度
  3. 所以这里的基本方法是在div内添加额外的#wrapper并且:

    1. 使图像与#wrapper
    2. 的大小相同
    3. 确保新的div足够大以适应图像,即使它已旋转
    4. 诀窍是弄清楚内包装应该有多大。那是金色的Pythagorean Theorem开始发挥作用的时候。

      使用一些数学,我们可以看出,对于500x300的图像,相对角之间的长度是583像素,并且有些变化。所以让我们将新的内部div设置为584px宽和高。

      <div id="wrapper" style="width: 500px; height: 300px;">
        <div id="content" style="width: 584px; height: 584px"></div>
      </div>
      

      然后,让我们确保将图像置于内部div的中心,这样当它旋转时,它总是适合。

      #content {
        position: relative;
      }
      #content img {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translateX(-50%) translateY(-50%);
      }
      

      从那里开始,鉴于#content内部的图像与#wrapper的图像尺寸完全相同,理论上我们应该很好。

      不幸的是,就支持任意大小的图像或灵活容器而言,这种解决方案并不灵活。我们可以使用任何calc()表达式来计算内部容器的大小(至少我能想出来),因为我们的操作仅限于加法,减法,乘法和除法,所以你需要自己计算这个数字并使用固定值。但确实有效,并且希望您的用例是PDF查看器,您的图像将始终具有相同的尺寸,因此您可以使其工作。

      这里唯一要明确的障碍是,当容器完全不旋转时,容器中的图像并不完全可见,这有点奇怪。为此,我可能会尝试使用JavaScript设置#wrapper的滚动位置以匹配图像的左上角。我会留给你的。

      <强>演示

      $('#slider').on('input', function(){
        $('#content').css("transform", "rotate(" + $("#slider").val() + "deg)");
      });
      #wrapper {
        padding: 0;
        width: 500px;
        height: 300px;
        overflow: auto;
      }
      #content {
        width: 584px;
        height: 584px;
        position: relative;
      }
      #content img {
        width: 500px;
        height: 300px;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translateX(-50%) translateY(-50%);
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div id="wrapper">
        <div id="content">
          <img src="https://www.w3schools.com/css/img_lights.jpg">
        </div>
      </div>
      <input id="slider" type="range" min="0" max="360" step="1" value="0">