【问题标题】:Angular Flip Animation角翻转动画
【发布时间】:2019-08-18 12:05:48
【问题描述】:

我正在尝试在 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;
}

【问题讨论】:

    标签: angular css animation flip angular-animations


    【解决方案1】:

    我认为您的代码rotateYscale3d后台逻辑存在三个问题。我不是 CSS 专家,如果需要修复后台逻辑,我无法为您提供很多帮助。如果对您的用例至关重要,这可能是另一个值得考虑的问题。

    旋转Y

    1. 您的起点(从后到前)是 180 度。这最初让卡片以 0 时间翻转一个方向来制作动画
    2. 你的动画方向是错误的,你需要动画负面明智。
    3. 所提供的解决方案仅在您未在动画中单击时才有效。因此,您需要等待 @flip.done 能够再次单击/动画。否则,您从 ~180deg - 0deg 旋转开始动画并以这种方式移动它

    Scale3d您没有使用初始值完成动画:scale3d(1, 1, 1)。我想这会导致一些奇怪的行为。

    背景逻辑如果您从 backfront 动画开始,您需要从 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
                })
              ]))
          ])
        ])

    希望能帮到你。如果我错了,请随时询问或纠正我

    【讨论】:

    • 感谢您的回复和 +1。我同意你的很多评​​价,我曾尝试过类似的解决方案,但无法通过从后到前翻转开始时的正面展示。
    【解决方案2】:

    我只需对原始代码稍作调整即可获得所需的行为。在 back => front 过渡中,rotateY 的起始值为 -180deg,而不是正 180deg。其他一切都是 100% 相同的。

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

    演示:https://angular-hzuxl9.stackblitz.io

    【讨论】:

      【解决方案3】:
      // card-flip
      @Component({
        selector: 'flip-card',
        template: `
          <div class="card-wrapper" (click)="cardFlipped = !cardFlipped" [@cardFlip]="cardFlipped">
            <div class="face front">FRONT</div>
            <div class="face back">BACK</div>
          </div>
        `,
        styles: [
          `
            .card-wrapper {
              transform-style: preserve-3d;
            }
      
            .face {
              position: absolute;
              height: 100%;
              backface-visibility: hidden;
            }
      
            .front {
              transform: rotateY(180deg);
            }
          `,
        ],
        animations: [
          trigger('cardFlip', [
            state('false', style({ transform: 'none' })),
            state('true', style({ transform: 'rotateY(180deg)' })),
            transition('false => true', animate('600ms ease-out')),
            transition('true => false', animate('600ms ease-out')),
          ]),
        ],
      })
      export class FlipCard {
        cardFlipped = false;
      }
      

      【讨论】:

      • 没有 cmets 只有代码?你应该描述你打算做什么以及你的代码解释什么是很重要的,因为它是对旧问题的迟到回答。
      猜你喜欢
      • 2018-04-22
      • 1970-01-01
      • 2011-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多