Я пытаюсь изменить размер повернутого (преобразованного с помощью CSS) объекта с помощью vanilla js. Происхождение объекта является центром и не может быть изменено.

Я нашел функцию здесь, которая должна делать это, но все же она не выглядит идеально - левый верхний угол меняет свою позицию (половина пикселей или около того).

Вот упрощенный пример codepen.

Какие модификации кода мне нужно сделать в getCorrection, чтобы всегда оставаться в левом верхнем углу?

ОБНОВИТЬ:

В соответствии с комментариями ниже, расчет точен, но браузер просто не может отлично справиться с долями пикселя, что кажется техническим ограничением? Есть идеи как починить?

4
Vytalyi 20 Дек 2019 в 18:24

2 ответа

Лучший ответ

Наконец я смог решить проблему с рендерингом субпикселей. Я немного изменил подход - вместо обновления левой и верхней координат со смещением, я использовал css translate (), чтобы применить то же смещение. Работает очень хорошо.

Кажется, у преобразования есть намного лучшие оптимизации рендеринга субпикселей.

Вот пример codepen.

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)';
}

Та же формула может быть повторно использована с небольшими изменениями, чтобы сохранить любой из углов прямоугольника.

2
Vytalyi 25 Дек 2019 в 21:10

Если вы применяете преобразования относительно верхнего левого угла (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>
2
Danziger 20 Дек 2019 в 15:36