Как выполнить 2 поворота при сбросе начала координат между каждым ключевым кадром?

#html #css #rotation #css-animations #keyframe

#HTML #css #поворот #css-анимации #ключевой кадр

Вопрос:

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

У меня поднята панель. Я пытаюсь повернуть его на 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 градусов.

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

Спасибо

Ответ №1:

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

 * {
  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>  

Ответ №2:

Я обнаружил, что порядок имеет значение в функции перевода. Все выполняется слева направо, поэтому начало поворота будет относительно текущего положения элемента, если вы выполните все слева направо (вот 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;
}