Имитация transform-origin с использованием translate - PullRequest
0 голосов
/ 28 июня 2018

Я хочу смоделировать свойства transform-origin, используя transform: translate в CSS.

Согласно MDN , это очень возможно:

Это свойство применяется, сначала переводя элемент в отрицательное значение свойства, затем применяя преобразование элемента, а затем переводя в значение свойства.

Однако при попытке получить неправильные результаты. Эти два прямоугольника явно не совпадают:

.origin {
  transform-origin: 100px 100px;
  transform: translate(100px, 0px) scale(2) rotate(45deg);
}

.translate {
  transform: translate(-100px, -100px) translate(100px, 0px) scale(2) rotate(45deg) translate(100px, 100px);
}

.box {
  background-color: red;
  width: 100px;
  height: 100px;
}

.container {
  float: left;
  margin: 100px;
  width: 250px;
  height: 250px;
  background-color: rgba(0, 0, 0, 0.1);
}
<div class="container">
  <div class="box origin">
  </div>
</div>

<div class="container">
  <div class="box translate">
  </div>
</div>

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

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

Вы почти хороши, но у вас есть две ошибки. Вам нужно инвертировать переводы и поменять transform-origin второго.

Если вы проверите документацию, вы увидите, что ссылка, используемая для перевода источника, - это верхний левый угол элемента, а значением по умолчанию для источника преобразования является center. Таким образом, мы должны иметь одинаковые ссылки для обоих.

.origin {
  transform-origin: 50px 50px;
  transform:  rotate(45deg) scale(2);
}
.translate {
  transform-origin:0 0; 
  transform:translate(50px, 50px) rotate(45deg) scale(2) translate(-50px, -50px);
} 
.box {
  background-color: red;
  width: 50px;
  height: 50px;
}
.container {
  display: inline-block;
  margin: 30px;
  width: 150px;
  height: 150px;
  background-color: rgba(0,0,0,0.1);
}
<div class="container">
  <div class="box origin">
  </div>
</div>
<div class="container">
  <div class="box translate">
  </div>
</div>

Вот из спецификации :

Матрица преобразования вычисляется из преобразования и transform-origin Свойства следующие:

  1. Начните с единичной матрицы.

  2. Перевести по вычисленным значениям X и Y из источника преобразования

  3. Умножьте на каждую из функций преобразования в свойстве transform из слева направо

  4. Перевести на отрицательные вычисленные значения X и Y для источника преобразования

Вам необходимо обратить внимание на формулировку! Вы можете обнаружить, что MDN противоречит спецификации, НО это не так просто потому, что существует разница между переводом элемента (как описано в MDN) и переводом источника элемента или локальная координата (как описано в спецификации).

Например, перевод элемента на -50px эквивалентен переводу его локальной координаты (начала координат) на + 50px.


Вам также необходимо обратить внимание на «Умножение слева направо» , так как это может привести к путанице. Если мы ссылаемся на ту же спецификацию в Примере 3, то имеем:

div {
  height: 100px; width: 100px;
  transform: translate(80px, 80px) scale(1.5, 1.5) rotate(45deg);
}

Это преобразование переводит локальную систему координат на 80 пикселей в обоих направлениях X и Y, затем применяет масштаб 150%, затем вращение на 45 ° по часовой стрелке вокруг оси Z. Влияние на рендеринг элемента может быть истолкован как применение этих преобразовывает в обратном порядке : элементы вращаются, затем масштабируются, потом перевел.

Таким образом, умножение слева направо не означает применения слева направо, что как-то объясняет необходимость инвертирования перевода, примененного вами для имитации transform-origin:

0 голосов
/ 28 июня 2018

transform-origin не может быть так легко смоделировано с использованием transform: translate. Используя transform-origin, вы изменяете центр преобразований, поэтому повороты и все остальные преобразования рассчитываются на основе другой точки.

Взгляните на приведенный ниже пример из MDN с transform-origin: 50px,50px. Повернутый элемент находится ниже нижнего края пунктирного квадрата по значению, которое невозможно легко вычислить. Вы, конечно, могли бы смоделировать transform-origin с transform: translate по значениям, необходимо рассчитать для конкретной комбинации значений.

enter image description here

...