调整旋转对象的大小,保留左上角(亚像素渲染问题)

Resize rotated object preserving left top corner (sub-pixel rendering issue)

我正在尝试使用 vanilla js 调整旋转(用 css 转换)对象的大小。对象原点位于中心且无法更改。

我找到了一个函数 here 应该可以完成这件事,但它看起来仍然不理想 - 左上角改变了它的位置(大约一半像素)。

这是一个简化的 codepen example

我需要在 getCorrection 处进行哪些代码修改以保持左上角位置始终相同?

更新:

根据下面的评论,计算是准确的,但浏览器无法完美处理像素的小数部分,这似乎是技术限制?有什么解决办法吗?

如果相对于左上角 (transform-origin: top left) 应用变换,则无需计算该校正因子。如果需要将它们放在页面上,您可以将所有形状包裹起来:

const obj = document.querySelector('.object');
const btn = document.querySelector('button');

let h = 100;
let w = 100;

btn.addEventListener('click', () => { 
  h += 5;
  w += 5;
  
  updateElement();
});

function updateElement() {
  obj.style.width = w + 'px';
  obj.style.height = h + 'px';
}

updateElement();
body {
  margin: 0;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  overflow-y: scroll;
  overflow-x: hidden;
}

button {
  margin: 8px;
  padding: 8px;
  font-family: monospace;
  border: 2px solid black;
  background: transparent;
}

.container {
  position: relative;   
  width: 100%;
  height: 100%;
}

.object-initial {
  position: absolute;
  top: 16px;
  left: 30%;
  outline: 1px dashed black;
  transform: rotate(20deg);
  transform-origin: top left;
  width: 100px;
  height: 100px;
}

.object {
  position: absolute;
  top: 16px;
  left: 30%;
  outline: 1px solid black;
  transform: rotate(20deg);
  transform-origin: top left;
}
<button>Increase width and height</button>

<div class="container">
  <div class="object"></div>

  <div class="object-initial"></div>
</div>

我终于能够解决子像素渲染的问题。我稍微改变了一种方法——我没有使用偏移更新左坐标和上坐标,而是使用 css translate() 来应用相同的偏移。效果很好。

似乎变换具有更好的子像素渲染优化。

这里是codepen example.

function updateElement() {
    obj.style.left = l + 'px';
    obj.style.top = t + 'px';
    obj.style.width = w + 'px';
    obj.style.height = h + 'px';
    obj.style.transform = 'rotate(' + r + 'deg) translate(' + ox + 'px, ' + oy + 'px)';
}

可以重复使用相同的公式,稍作调整以保留任何矩形角。