почему эта ключевая анимация формирует этот анимационный эффект - PullRequest
0 голосов
/ 05 октября 2018

Я видел эту анимацию на codepen, и я не знаю, почему она написана таким образом, чтобы получить этот эффект, но я думаю, что он будет иметь эффект вращения на 360 градусов по часовой стрелке, на 360 градусов против часовой стрелки, вместо того, чтобы подпрыгивать вверх или вниз иливлево и вправо

Я особенно озадачен анимацией ключевого кадра

@keyframes move{
    from {
       transform: rotate(360deg) translateX(1.125em) rotate(-360deg);
    }
    to {
       transform: rotate(-360deg) translateX(1.125em) rotate(360deg);
    }
}

Результаты следующие

https://i.stack.imgur.com/9oWnw.gif

1 Ответ

0 голосов
/ 05 октября 2018

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

Если from-to-transform имеют одинаковое количество функций преобразования, каждая пара функций преобразования имеет либо одинаковое имя, либо является производной от одного и того же примитива:Интерполируйте каждую пару функций преобразования, как описано в разделе Интерполяция функций преобразования.Вычисленное значение является результирующим списком функций преобразования.

Таким образом, браузер изменит первый rotate с 360deg на -360deg и то же самое для последнего rotate, в то время как translateXбудет оставаться прежним.Затем у нас будут следующие шаги:

transform: rotate(360deg) translateX(1.125em) rotate(-360deg);
transform: rotate(350deg) translateX(1.125em) rotate(-350deg);
transform: rotate(340deg) translateX(1.125em) rotate(-340deg);
....
transform: rotate(0) translateX(1.125em) rotate(0);
....
....
transform: rotate(-360deg) translateX(1.125em) rotate(360deg);

Теперь нам нужно понять, как работает rotate(-adeg) translateX(b) rotate(adeg).Во-первых, вы можете заметить, что вращение не окажет никакого визуального влияния на элемент, так как мы имеем дело с кругом, оно просто повлияет на , как будет работать перевод , а точнее - на первое вращение, которое важно (тот, что слева).

.container {
  width: 50px;
  height: 50px;
  margin: 50px;
  border:2px solid;
}

.box {
  width: 50px;
  height: 50px;
  background: red;
  border-radius: 50%;
  animation: move 2s linear infinite;
}

.alt {
  animation: move-alt 2s linear infinite;
}

@keyframes move {
  from {
    transform: rotate(360deg) translateX(1.125em) rotate(-360deg);
  }
  to {
    transform: rotate(-360deg) translateX(1.125em) rotate(360deg);
  }
}

@keyframes move-alt {
  from {
    transform: rotate(360deg) translateX(1.125em);
  }
  to {
    transform: rotate(-360deg) translateX(1.125em);
  }
}
<div class="container">
  <div class="box">

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

  </div>
</div>

Как вы можете видеть, обе анимации эквивалентны визуально .

Теперь эффект выглядит следующим образом: каждый раз, когда мыповерните ось X, а затем мы переводим наш элемент с учетом новой повернутой оси.Это как вращение системы координат, затем мы переводим ИЛИ, как если бы мы делали перевод один раз (поскольку это то же самое), тогда мы продолжаем вращать систему координат, поэтому у нас есть вращение в конце.

enter image description here

Теперь, если мы рассмотрим обратное преобразование, ничего визуально не произойдет:

.container {
  width: 50px;
  height: 50px;
  margin: 50px;
  border: 2px solid;
}

.box {
  width: 50px;
  height: 50px;
  background: red;
  border-radius: 50%;
  animation: move 2s linear infinite;
}

@keyframes move {
  from {
    transform: translateX(1.125em) rotate(-360deg);
  }
  to {
    transform: translateX(1.125em) rotate(360deg);
  }
}
<div class="container">
  <div class="box">

  </div>
</div>

В этом случае мы переводим систему координат таким же переводом, а затем вращаем наш круг.Если мы изменим его на квадрат, мы увидим эффект

.container {
  width: 50px;
  height: 50px;
  margin: 50px;
  border: 2px solid;
}

.box {
  width: 50px;
  height: 50px;
  background: red;
  animation: move 2s linear infinite;
}

@keyframes move {
  from {
    transform: translateX(1.125em) rotate(-360deg);
  }
  to {
    transform: translateX(1.125em) rotate(360deg);
  }
}
<div class="container">
  <div class="box">

  </div>
</div>

А вот как будет выглядеть ваша первоначальная анимация с квадратом:

.container {
  width: 50px;
  height: 50px;
  margin: 50px;
  border: 2px solid;
}

.box {
  width: 50px;
  height: 50px;
  background: red;
  animation: move 2s linear infinite;
}

@keyframes move {
  from {
    transform:rotate(360deg) translateX(1.125em) rotate(-360deg);
  }
  to {
    transform:rotate(-360deg) translateX(1.125em) rotate(360deg);
  }
}
<div class="container">
  <div class="box">

  </div>
</div>

Мы вращаем систему координат, мы переводим наш элемент, затем мы вращаем элемент так, как будто мы вращаем наш элемент внутри большего элемента, который также вращается вобратное направление.

Если вы измените функцию синхронизации на что-то другое, чем линейное, у вас будет такое же вращение, но оно не будет линейным, оно будет медленнее / быстрее в некотором интервале:

.container {
  width: 50px;
  height: 50px;
  margin: 50px;
  border: 2px solid;
}

.box {
  width: 50px;
  height: 50px;
  background: red;
  animation: move 2s ease-in-out infinite;
}

@keyframes move {
  from {
    transform:rotate(360deg) translateX(1.125em) rotate(-360deg);
  }
  to {
    transform:rotate(-360deg) translateX(1.125em) rotate(360deg);
  }
}
<div class="container">
  <div class="box">

  </div>
</div>

Это упрощенное объяснение, вы можете проверить этот ответ, если вы хотите узнать больше о том, как мы работаем с несколькими функциями внутри преобразования и как порядокважно: Имитация источника преобразования с использованием translate

...