【问题标题】:Calculate transform-origin to scale image to middle of viewport计算变换原点以将图像缩放到视口中间
【发布时间】:2017-08-31 14:33:56
【问题描述】:

我正在尝试在 javascript transform-origin 属性中计算绝对定位的元素,以便它们在悬停时填充整个视口。

我尝试通过将 x 除以窗口宽度和 y 除以窗口高度来计算此属性,其中 x 是从左视口边缘到元素中心的距离,y 是视口顶部和元素中心之间的距离。不幸的是,元素并没有以这种方式完美居中,并且没有像我想要的那样填满整个屏幕,尽管它有合适的大小来填满屏幕:/

如何正确计算transform-origin 的枢轴位置以实现我想要的?

这里有一个演示:

let blocks = document.querySelectorAll("a.block");
console.log(blocks);

Array.prototype.slice.call(blocks).forEach((block) => {
	console.log(block);
  let blockRect = block.getBoundingClientRect();
	
  let originX = (blockRect.left + blockRect.width /2) / window.innerWidth * 100,
  	originY = (blockRect.top + blockRect.height /2) / window.innerHeight * 100;
	block.style.transformOrigin = `${originX}% ${originY}%`;
});
.block{
  position: absolute;
  left: 5%;
  top: 10%;
  width: 10%;
  height: 10%;
  background: red;
  -webkit-transition: transform 1s;
  transition: transform 1s;
}
  
.block.second{
  left: 87%;
  top: 26%;
}
.block:hover{
  -webkit-transform: scale3d(10,10,1);
  transform: scale3d(10,10,1);
}
 <a href="#" class="block"></a>
 <a href="#" class="block second"></a>

【问题讨论】:

    标签: javascript html css transform


    【解决方案1】:

    您有什么特殊原因要使用 JavaScript 执行此操作吗?如果您只想要动画,您可以使用纯 css 来完成,只需将元素的位置和尺寸设置为覆盖整个页面并使用过渡来很好地动画它:

    .block{
      position: absolute;
      left: 5%;
      right: 85%;
      top: 10%;
      bottom: 80%;
      width: 10%;
      height: 10%;
      background: red;
      -webkit-transition: all 1s;
      transition: all 1s;
    }
    
    .block.second{
      left: 87%;
      top: 26%;
    }
    .block:hover{
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
      width: 100%;
      height: 100%;
    }
    

    【讨论】:

    • 我必须使用 3d 变换,因为在这种情况下我需要非常平滑的过渡。所有元素都是用js随机排列的,所以我不能使用纯css,因为我不知道运行中的元素位置。此外,您的解决方案不适用于连接到底部边缘的元素:JsFiddle
    • 实际上有一个错误。您必须在初始 .block 定义中设置顶部、左侧、右侧和底部值。我已将答案更改为正确的版本。有一个问题:放置这些框时,您必须计算正确的百分比,以便顶部 + 高度 + 底部 = 100%,但这应该很容易。由于我们使用的是内置浏览器功能,因此它也应该运行顺畅。但是你必须检查这是否足够顺利。
    • 感谢您的帮助。我找到了正确的数学公式来做这件事。我将在性能方面测试这两种解决方案并选择最佳答案;)
    【解决方案2】:

    我更新了几何变换的知识,找到了正确的数学公式。

    transform-origin-x = scale * x / (scale-1)
    transform-origin-y = scale * y / (scale-1)
    

    其中 x 和 y 是距 [left for x, top for y] 边缘的距离,转换为与元素宽度相同的单位。

    要将距离(以像素为单位)转换为百分比,您可以:

    Percentage x distance = left[px] / window.innerWidth[px] * 100
    Percentage y distance = top[px] / window.innerHeight[px] * 100
    

    let blocks = document.querySelectorAll("a.block");
    
    Array.prototype.slice.call(blocks).forEach((block) => {
    
      let blockRect = block.getBoundingClientRect();
    	
    	let originX = (10 * (blockRect.left/window.innerWidth * 100)) / 9,
      	originY =  (10 * (blockRect.top/window.innerHeight * 100)) / 9;
      
    
    	block.style.transformOrigin = `${originX}% ${originY}%`;
    });
    .block{
      position: absolute;
      left: 5%;
      bottom: 10%;
      width: 10%;
      height: 10%;
      background: red;
      -webkit-transition: transform 1s;
      transition: transform 1s;
    
    }
    
    .block.second{
      left: 87%;
      bottom: auto;
      top: 17%;
    }
    
    .block:hover{
      -webkit-transform: scale3d(10,10,1);
      transform: scale3d(10,10,1);
    }
    <a href="#" class="block"></a>
     <a href="#" class="block second"></a>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-09
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      相关资源
      最近更新 更多