Анимация углового флип - PullRequest
1 голос
/ 27 марта 2019

Я пытаюсь сделать флип анимацию в Angular. При щелчке она должна перевернуться по оси Y, затем при щелчке снова перевернуться по оси Y в обратном направлении. Кроме того, он должен иметь содержимое лицевой и оборотной сторон, которое отображается в зависимости от состояния переворачивания.

Сальто назад доставляет мне горе. Я получаю странное поведение в зависимости от того, что я пытаюсь. Лучшее, что я смог сделать, - это странный переворот, который начинается в том же направлении, что и переворот спереди назад, а затем меняет направление в конце. * Пожимает *

Обратите внимание, что если вы щелкнете по нему до завершения анимации, он будет работать как нужно. Если вы ждете, пока анимация завершится, то у вас будет вышеупомянутое поведение.

Вот прототип: https://angular -epkrtn.stackblitz.io

Кто-нибудь может помочь с переворотом назад-вперед?


Копирование кода по ссылке ниже

app.component.ts

import { Component } from '@angular/core';
import { trigger, transition, animate, style, keyframes, state } from '@angular/animations';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ],
    animations: [
    trigger('flip', [
      state('front', style({
        transform: 'rotateY(0deg)'
      })),
      state('back', style({
        transform: 'rotateY(180deg)'
      })),
      transition('front => back', [
        animate('1s 0s ease-out',
          keyframes([
            style({
              transform: 'perspective(400px) rotateY(0deg)',
              offset: 0
            }),
            style({
              transform: 'perspective(400px) scale3d(1.5, 1.5, 1.5) rotateY(80deg)',
              offset: 0.4
            }),
            style({
              transform: 'perspective(400px) scale3d(1.5, 1.5, 1.5) rotateY(100deg)',
              offset: 0.5
            }),
            style({
              transform: 'perspective(400px) scale3d(0.95, 0.95, 0.95) rotateY(180deg)',
              offset: 0.8
            }),
            style({
              transform: 'perspective(400px) rotateY(180deg)',
              offset: 1
            })
          ]))
      ]),
      transition('back => front', [
        animate('1s 0s ease-in',
          keyframes([
            style({
              transform: 'perspective(400px) rotateY(180deg)',
              offset: 0
            }),
            style({
              transform: 'perspective(400px) scale3d(1.5, 1.5, 1.5) rotateY(100deg)',
              offset: 0.4
            }),
            style({
              transform: 'perspective(400px) scale3d(1.5, 1.5, 1.5) rotateY(80deg)',
              offset: 0.5
            }),
            style({
              transform: 'perspective(400px) scale3d(0.95, 0.95, 0.95) rotateY(0deg)',
              offset: 0.8
            }),
            style({
              transform: 'perspective(400px) rotateY(0deg)',
              offset: 1
            })
          ]))
      ])
    ])
  ]
})
export class AppComponent  {
  flipState = 'front';

  onFlipClick() {
    if (this.flipState == 'front') {
      this.flipState = 'back';
    } else {
      this.flipState = 'front';
    }
  }
}

app.component.html

<div (click)="onFlipClick()" class="flip-card">
    <div [@flip]="flipState" class="flip-card-inner">
        <div class="flip-card-front">
            FRONT
        </div>
        <div class="flip-card-back">
            BACK
        </div>
    </div>
</div>

app.component.css

.flip-card {
    height: 200px; 
    width: 200px; 
    background-color: transparent;
    margin-top: 250px;
    margin-left: auto; 
    margin-right: auto;
}

.flip-card-inner {
    position: relative;
    height: 100%;
    width: 100%;
    transform-style: preserve-3d;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
}

.flip-card-inner > div {
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
}

.flip-card-front {
    background-color: blue;
}

.flip-card-back {
    transform: rotateY(180deg);
    background-color: green;
}

Ответы [ 2 ]

1 голос
/ 28 марта 2019

Мне удалось получить желаемое поведение с незначительными изменениями исходного кода.В переходе back => front начальное значение rotateY - -180 градусов, а не положительное 180 градусов.Все остальное на 100% идентично.

  transition('back => front', [
    animate('1s 0s ease-in',
      keyframes([
        style({
          transform: 'perspective(400px) rotateY(-180deg)',
          offset: 0
        }),

Демонстрация: https://angular -hzuxl9.stackblitz.io

1 голос
/ 28 марта 2019

Я думаю, что есть три проблемы с вашим кодом rotateY , scale3d и Фоновая логика . Я не эксперт по CSS и не могу вам помочь с фоновой логикой , если ее нужно исправить. Возможно, это еще один вопрос, если он имеет решающее значение для вашего варианта использования.

Поворот Y

  1. Ваша начальная точка (спереди назад) - 180 градусов. Это изначально позволяет карте перевернуться в один конец с 0 раз, чтобы оживить
  2. Ваше направление анимации неправильное, вам нужно анимировать негативно.
  3. Предоставленное решение работает только в том случае, если вы не щелкаете внутри анимации. Поэтому вам нужно подождать, пока @ flip.done сможет снова нажать / анимировать. В противном случае вы начнете анимацию с поворота на ~ 180 градусов и 0 градусов и передвинете его так

Scale3d Вы не завершаете анимацию с начальным значением: scale3d (1, 1, 1) . Я думаю, это может вызвать странное поведение.

Фоновая логика Если вы запускаете анимацию от назад до front , вам нужно сначала начать анимацию с 0 градусов. Это вызовет появление фронта, потому что ваш стиль там сломан - поэтому у меня пока нет решения.

Ссылка, которая исправила анимацию : Flip Animation

Полный код

trigger('flip', [
      state('front', style({
        transform: 'rotateY(0deg)'
      })),
      state('back', style({
        transform: 'rotateY(180deg)'
      })),
      transition('front => back', [
        animate('1s 0s ease-out',
          keyframes([
            style({
              transform: 'perspective(400px) rotateY(0deg)',
              offset: 0
            }),
            style({
              transform: 'perspective(400px) scale3d(1.5, 1.5, 1.5) rotateY(80deg)',
              offset: 0.4
            }),
            style({
              transform: 'perspective(400px) scale3d(1.5, 1.5, 1.5) rotateY(100deg)',
              offset: 0.5
            }),
            style({
              transform: 'perspective(400px) scale3d(0.95, 0.95, 0.95) rotateY(180deg)',
              offset: 0.8
            }),
            style({
              transform: 'perspective(400px) scale3d(1, 1, 1) rotateY(180deg)',
              offset: 1
            })
          ]))
      ]),
      transition('back => front', [
        animate('1s 0s ease-in',
          keyframes([
            style({
              transform: 'perspective(400px) rotateY(0deg)',
              offset: 0
            }),
            style({
              transform: 'perspective(400px) scale3d(1.5, 1.5, 1.5) rotateY(-80deg)',
              offset: 0.4
            }),
            style({
              transform: 'perspective(400px) scale3d(1.5, 1.5, 1.5) rotateY(-100deg)',
              offset: 0.5
            }),
            style({
              transform: 'perspective(400px) scale3d(0.95, 0.95, 0.95) rotateY(-180deg)',
              offset: 0.8
            }),
            style({
              transform: 'perspective(400px) scale3d(1, 1, 1) rotateY(-180deg)',
              offset: 1
            })
          ]))
      ])
    ])

Надеюсь, я смогу вам помочь. Не стесняйтесь спрашивать больше или исправить меня, если я ошибаюсь

...