Как сделать 2+ поворота при сбросе начала координат между каждым во время ключевого кадра? - PullRequest
0 голосов
/ 23 апреля 2019

Я пытаюсь сделать анимированную коробку, которая развернется при загрузке страницы.

Я поднял панель. Я пытаюсь повернуть его на 90 градусов к земле, и после этого я хотел бы снова поднять его, опираясь на другой край 90 градусов.

Я пытался изменить источник (transform-origin: top), но он изменил источник на исходный. Мне пришлось добавить 2 перевода, чтобы разместить его в нужном месте, но это создает удар. Край на земле не прилипает к земле.

Вот моя текущая скрипка: https://jsfiddle.net/hbnta1uj/2/

Я также пытался без изменения источника, но я все еще получаю удар:

@keyframes slideFront2 {
    0% {
        transform: rotateX(-0deg);
    }
    50% {
        transform: rotateX(-90deg);
    }
    100% {
        transform: rotateX(-180deg) translateZ(-100px) translateY(100px);
    }
}

У меня есть еще одна идея, где я уже позиционирую вторую панель плоско и скрываю ее (непрозрачность 0), и при 50%, когда первая панель плоская, я показываю вторую и просто на 90 градусов.

Но я бы хотел знать для более сложных анимаций, есть ли способ сделать это так, как я описываю, всегда начинать с новой позиции новое преобразование?

Спасибо

Ответы [ 2 ]

0 голосов
/ 25 апреля 2019

Я обнаружил, что порядок следования в функции перевода.Все выполняется слева направо, поэтому начало вращения будет относительно текущей позиции элемента, если вы выполните все слева направо (Вот 2 блока, получающих одинаковый перевод вращения, но порядок отличается: https://codepen.io/anon/pen/oOQGPp)

Так что в моем примере, если вы сделаете:

    50.001% {
        transform: rotateX(90deg) translateZ(00px) translatey(100px) ;
        transition-timing-function: linear;
    }
    100% {
        transform: rotateX(0deg) translateZ(100px) translatey(00px) ;
        transition-timing-function: linear;
    }

Поворот будет применен до перевода, поэтому начало вращения не будет нижней строкой после перевода, но это будет позиция без источникаоснованный на переведенной части (таким образом, это будет исходная позиция 0%.) CSS не сможет проложить путь анимации и добавит небольшой удар.

Но если вы сделаете transform: TRANSLATE ROTATE,вращение будет применено после перевода, поэтому начало вращения будет связано с позицией с переводом. Вот как я смог повернуть элемент, не получив небольшую ошибку.

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

* {
    box-sizing: inherit;
    margin: 0;
}

html {
    box-sizing: border-box;
}

.container {
    width: 90%;
    margin: auto;
    height: 100vh;
    background-color: rgb(194, 194, 194);
}
.progressbar-wrapper {
    width: 300px;
    height: 100px;
    top: 50%;
    left: 50%;
    position: absolute;
    transform: translate(-50%, -50%);
}
.progressbar {
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transform: rotateX(-20deg) rotateY(-30deg);
}

.side {
    width: 100%;
    height: 100%;
    background-color: rgba(254, 254, 254, 0.3);
    position: absolute;
    top: 0;
    left: 0;
}

@keyframes slideBottom {
    0% {
        transform: rotateX(-0deg);
    }
    100% {
        transform: rotateX(-90deg);
    }
}
@keyframes slideFront {
    0% {
        transform: rotateX(-0deg);
    }
    50% {
        transform: rotateX(-90deg);
    }
    50.001% {
        transform: translateZ(100px) rotateX(90deg);
        transition-timing-function: linear;
    }
    100% {
        transform: translateZ(100px) rotateX(0deg) ;
        transition-timing-function: linear;
    }
}

.bottom {
    animation: 0.5s ease-out 0s 1 slideBottom forwards;
    box-shadow: 10px 10px 50px 5px rgba(90, 90, 90, 0.7);
    transform-origin: bottom;
}

.back {
    animation: 1s ease-out 0s 1 slideFront forwards;
    transform-origin: bottom;
}
0 голосов
/ 24 апреля 2019

Я бы рассмотрел анимацию на контейнере, чтобы было проще, когда вам нужен только один ключевой кадр:

* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

.container {
  width: 90%;
  margin: auto;
  height: 100vh;
  background-color: rgb(194, 194, 194);
}

.progressbar-wrapper {
  width: 300px;
  height: 100px;
  top: calc(50% - 50px);
  left: calc(50% - 150px);
  position: absolute;
  transform-style: preserve-3d;
  transform: rotateX(-20deg) rotateY(-30deg);
}

.progressbar {
  width: 100%;
  height: 100%;
  transform-origin: bottom;
  animation: 0.5s ease-out 1 slideFront forwards;
  transform-style: preserve-3d;
}

.side {
  width: 100%;
  height: 100%;
  background-color: rgba(254, 254, 254, 0.3);
  position: absolute;
  top: 0;
  left: 0;
}

@keyframes slideFront {
  100% {
    transform: rotateX(-90deg);
  }
}

.bottom {
  box-shadow: 10px 10px 50px 5px rgba(90, 90, 90, 0.7);
}

.back {
  animation: 1s ease-out 0.5s 1 slideFront forwards;
  transform-origin: top;
}
<div class="container">
  <div class="progressbar-wrapper">
    <div class="progressbar">
      <div class="side back">
      </div>
      <div class="side bottom">
      </div>
    </div>
  </div>
</div>
...