我在创建一种带有 Angular 动画的轮播时遇到问题。它用于具有不同步骤的注册表单。当你进入下一步时,它必须从右侧滑动,当你返回时,它必须从左侧滑动。
我没能创建一个 plnkr 示例,无法导入 Angular 动画,抱歉。
这里有一个基本代码,可以让您了解我正在寻找的内容:
animations: [
trigger('slideRight', [
state('in', style({ transform: 'translateX(0%)' })),
state('out', style({ transform: 'translateX(+100%)' })),
transition('in <=> out', animate('200ms ease-in')),
transition('out <=> in', animate('200ms ease-in-out'))
]),
trigger('slideLeft', [
state('in', style({ transform: 'translateX(0%)' })),
state('out', style({ transform: 'translateX(-100%)' })),
transition('in <=> out', animate('200ms ease-in')),
transition('out <=> in', animate('200ms ease-in-out'))
])
]
signingUpStep: 0;
<div>
<div [hidden]="signingUpStep != 0" [@slideLeft]="signingUpStep == 0 ? 'in' : 'out'">
<div>Step 0</div>
</div>
<div [hidden]="signingUpStep != 1" [@slideRight]="signingUpStep == 1 ? 'in' : 'out'">
<div>Step 1</div>
</div>
<div [hidden]="signingUpStep != 2" [@slideRight]="signingUpStep == 2 ? 'in' : 'out'">
<div>Step 2</div>
</div>
</div>
我的问题是:
<div [hidden]="signingUpStep != 1" [@slideRight]="signingUpStep == 1 ? 'in' : 'out'">
<div>Step 1</div>
</div>
它总是使用[@slideRight]动画,而我希望当用户来自signingUpStep == 0时它确实使用[@slideRight],但当用户来自signingUpStep == 2时使用[@slideLeft]。
就像中间的 divsigningUpStep == 1 位于轮播的中间。
我读过有关 :increment 和 :decrement 的内容,但我不确定如何使用它们。
我也尝试使用参数,但它没有像我想要的那样工作。我需要能够根据幻灯片中的用户位置动态更改参数。
谢谢你。
我有一个类似的问题,并设法使用参数仅使用一个动画触发器来做到这一点:
trigger('slideInOut', [
transition(':enter', [
style({ transform: 'translateX({{direction}}%)' }),
animate('400ms ease-in', style({ transform: 'translateX(0%)' })),
]),
])
在模板上(它是一个数据轮播,所以我将导航方向从右到左更改为从左到右):
<div class="envolvido"
*ngFor="let envolvido of itensPaginaAtual; index as indexOfelement"
[@slideInOut]="{ value: '',
params: { direction: this.direction === 'RL' ? '100' : '-100' } }"
>
你是对的,解决方案涉及使用
:increment
和 :decrement
。这个想法是,你有一个计数器,当旋转木马向前移动时,它会增加,当旋转木马向后移动时,它会减少。这为您提供了转换可以挂钩的状态更改。您还需要使用 query()
函数来捕获进入和退出轮播的幻灯片,并使用 group()
函数来确保进入和退出动画并行运行。
请参阅 Stackblitz
的演示carousel.component.ts
import { Component, HostBinding } from '@angular/core';
import {
trigger,
style,
animate,
transition,
query,
group,
} from '@angular/animations';
const ANIMATION_TIMING = '600ms ease-out';
@Component({
selector: 'app-carousel',
templateUrl: './carousel.component.html',
styleUrls: ['./carousel.component.css'],
animations: [
trigger('trigger', [
transition(':increment', [
group([
query(
':enter',
[
style({ transform: 'translate(100%, 0)' }),
animate(
ANIMATION_TIMING,
style({ transform: 'translate(0, 0)' })
),
],
{ optional: true }
),
query(
':leave',
[
animate(
ANIMATION_TIMING,
style({ transform: 'translate(-100%, 0)' })
),
],
{ optional: true }
),
]),
]),
transition(':decrement', [
group([
query(
':enter',
[
style({ transform: 'translate(-100%, 0)' }),
animate(
ANIMATION_TIMING,
style({ transform: 'translate(0, 0)' })
),
],
{ optional: true }
),
query(
':leave',
[
animate(
ANIMATION_TIMING,
style({ transform: 'translate(100%, 0)' })
),
],
{ optional: true }
),
]),
]),
]),
],
})
export class CarouselComponent {
@HostBinding('@trigger') public signingUpStep: number = 0;
direction = '';
onNavigate(event: string) {
this.direction = event;
if (this.direction === 'prev') {
this.signingUpStep = Math.max(0, this.signingUpStep - 1);
} else {
// hardcoding the number of steps here - not the best!
this.signingUpStep = Math.min(3, this.signingUpStep + 1);
}
}
}
carousel.component.html
<app-step
[step]="signingUpStep"
*ngIf="signingUpStep === 0"
index="0"
imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/2/22/Malus_domestica_a1.jpg/220px-Malus_domestica_a1.jpg"
(navigate)="onNavigate($event)"
></app-step>
<app-step
[step]="signingUpStep"
*ngIf="signingUpStep === 1"
index="1"
imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4c/Bananas.jpg/1280px-Bananas.jpg"
(navigate)="onNavigate($event)"
></app-step>
<app-step
[step]="signingUpStep"
*ngIf="signingUpStep === 2"
index="2"
imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Carrots_at_Ljubljana_Central_Market.JPG/1920px-Carrots_at_Ljubljana_Central_Market.JPG"
(navigate)="onNavigate($event)"
></app-step>
<app-step
[step]="signingUpStep"
*ngIf="signingUpStep === 3"
index="3"
imageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/Persea_americana_fruit_2.JPG/800px-Persea_americana_fruit_2.JPG"
(navigate)="onNavigate($event)"
></app-step>
carousel.component.css
:host {
display: block;
border: solid 2px hotpink;
position: relative;
height: 300px;
overflow: hidden;
}
* {
box-sizing: border-box;
}
step.component.ts
import {
Component,
EventEmitter,
HostBinding,
Input,
Output,
} from '@angular/core';
@Component({
selector: 'app-step',
templateUrl: './step.component.html',
styleUrls: ['./step.component.css'],
})
export class StepComponent {
@Input() step: number;
@Output() navigate: EventEmitter<string> = new EventEmitter();
@Input() imageUrl: string = '';
@HostBinding('style.backgroundImage') @Input() get backgroundImage() {
return `url(${this.imageUrl})`;
}
clickNext() {
this.navigate.emit('next');
}
clickPrev() {
this.navigate.emit('prev');
}
}
step.component.html
<h2>Step {{step}}</h2>
<!-- hard coding number of steps here - not the best! -->
<button *ngIf="step > 0" (click)="clickPrev()">Prev</button>
<button *ngIf="step < 3" (click)="clickNext()">Next</button>
step.component.css
:host {
display: block;
padding: 10px;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
background-size: cover;
background-repeat: no-repeat;
}