Angular翻转动画
Angular Flip Animation
我正在尝试在 Angular 中制作翻转动画。它应该在单击时翻转 Y 轴,然后在再次单击时以相反方向翻转回 Y 轴。此外,它应该具有根据翻转状态显示的正面和背面内容。
从后到前的翻转让我很伤心。根据我的尝试,我会出现奇怪的行为。我能做的最好的事情是一个奇怪的翻转,它以与从前到后翻转相同的方向开始,然后在最后改变方向。 *耸肩*
请注意,如果您在动画结束前单击它,它会按预期工作。如果你等待它完成动画,那么它就会有上述行为。
这是原型:https://angular-epkrtn.stackblitz.io
有人可以帮忙从后到前翻转吗?
正在复制下面 link 中的代码
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;
}
我认为您的代码存在三个问题rotateY、scale3d和后台逻辑.我不是 CSS 专家,如果需要修复 后台逻辑 ,我无法为您提供很多帮助。如果对您的用例至关重要,这可能是另一个值得提出的问题。
旋转 Y
- 你的起点(从后到前)是 180 度。最初让卡片以 0 时间翻转一个方向来制作动画
- 你的动画方向错了,你需要做负方向的动画。
- 提供的解决方案仅在您不在动画内单击时有效。所以你需要等待@flip.done能够再次click/animate。否则你从 ~180deg - 0deg 旋转开始动画并以这种方式移动它
Scale3d 您没有使用初始值完成动画:scale3d(1, 1, 1)。我想这会导致一些奇怪的行为。
背景逻辑 如果你开始你的back到front动画你需要开始你的动画在 0deg。这将导致前面出现,因为你的样式在那里被破坏了 - 因此我还没有解决方案。
Link 修复了动画: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
})
]))
])
])
希望能帮到你。如果我错了,请随时询问或纠正我
我只需对原始代码稍作调整就可以获得所需的行为。在 back => front 过渡中,rotateY 的起始值为 -180deg,而不是正 180deg。其他一切都是 100% 相同的。
transition('back => front', [
animate('1s 0s ease-in',
keyframes([
style({
transform: 'perspective(400px) rotateY(-180deg)',
offset: 0
}),
// 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;
}
我正在尝试在 Angular 中制作翻转动画。它应该在单击时翻转 Y 轴,然后在再次单击时以相反方向翻转回 Y 轴。此外,它应该具有根据翻转状态显示的正面和背面内容。
从后到前的翻转让我很伤心。根据我的尝试,我会出现奇怪的行为。我能做的最好的事情是一个奇怪的翻转,它以与从前到后翻转相同的方向开始,然后在最后改变方向。 *耸肩*
请注意,如果您在动画结束前单击它,它会按预期工作。如果你等待它完成动画,那么它就会有上述行为。
这是原型:https://angular-epkrtn.stackblitz.io
有人可以帮忙从后到前翻转吗?
正在复制下面 link 中的代码
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;
}
我认为您的代码存在三个问题rotateY、scale3d和后台逻辑.我不是 CSS 专家,如果需要修复 后台逻辑 ,我无法为您提供很多帮助。如果对您的用例至关重要,这可能是另一个值得提出的问题。
旋转 Y
- 你的起点(从后到前)是 180 度。最初让卡片以 0 时间翻转一个方向来制作动画
- 你的动画方向错了,你需要做负方向的动画。
- 提供的解决方案仅在您不在动画内单击时有效。所以你需要等待@flip.done能够再次click/animate。否则你从 ~180deg - 0deg 旋转开始动画并以这种方式移动它
Scale3d 您没有使用初始值完成动画:scale3d(1, 1, 1)。我想这会导致一些奇怪的行为。
背景逻辑 如果你开始你的back到front动画你需要开始你的动画在 0deg。这将导致前面出现,因为你的样式在那里被破坏了 - 因此我还没有解决方案。
Link 修复了动画: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
})
]))
])
])
希望能帮到你。如果我错了,请随时询问或纠正我
我只需对原始代码稍作调整就可以获得所需的行为。在 back => front 过渡中,rotateY 的起始值为 -180deg,而不是正 180deg。其他一切都是 100% 相同的。
transition('back => front', [
animate('1s 0s ease-in',
keyframes([
style({
transform: 'perspective(400px) rotateY(-180deg)',
offset: 0
}),
// 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;
}