问题
I'm working with Angular4 and their animation. I'm trying to pass dynamic values to an animation declaration but it revers to it's original state after the animation finishes.
Basically, I have a dynamic height that will then trigger the animation based on that height.
I'd like to make this work without bootstrap, or flat out css3 approaches and do it in angular's animation.
Below is the animation definition
export const deltaScore = trigger(
"deltaScore",
[
state("void", style({
height: "*"
}
)
),
state('*', style({ height: "*" })),
state('update', style({ height: "{{height}}" })),
transition(
"* => *",
[style({height: "*"}), animate('1s ease-in')]
),
transition(
"* <=> update",
[style({height: "*"}), animate('1s ease-in')]
)
], { height: 0 }
);
Updated: plunk
回答1:
Instead of using triggers and states, you could use the AnimationBuilder, which simplifies things and I think it's best fitted for situations like these, when you don't need state and triggers. And the end result of the animation is kept, of course, until you decide to do another animation.
Template:
<div class="progress-wrap">
{{progress}}
<div #progressBar class="progress-bar"></div>
</div>
Component:
import { ElementRef } from '@angular/core';
import { AnimationBuilder, animate, style } from '@angular/animations';
@Component({
// ...
})
export class MyComponent {
@ViewChild('progressBar') progressBar: ElementRef;
animationPlayer;
constructor(
private animBuilder: AnimationBuilder
) {}
updateProgress(progress = null): void {
const progressAnimation = this.animBuilder.build([
animate(`430ms ease-out`, style({
'height': `${!!progress ? progress + '%' : '*'}`
}))
]);
this.animationPlayer = progressAnimation.create(this.progressBar.nativeElement);
this.animationPlayer.onDone((evt) => {
console.log('ANIMATION DONE', evt);
// there is no notion of 'trigger' or 'state' here,
// so the only thing this event gives you is the 'phaseName',
// which you already know...
// But the done callback is here and you can do whatever you might need to do
// for when the animation ends
});
this.animationPlayer.play();
}
}
Then, you can simply:
this.updateProgress(80); // to animate the progress bar to 80%
this.updateProgress(); // in case you want to animate to an 'auto' height (not that it would be needed on a progress animation, but for other cases)
I've made some adjustments to the plnkr to use animation builder for the progress and for the growth: https://plnkr.co/edit/K1r3I8QZOmMIAGEYC2fw?p=preview
Of course, you don't need to have 'animationPlayer' as a property of your class... It can simply be a local variable in your method, but maybe you want to access the same instance from within another method, pause it or end it manually.
P.S. state()
should definitely be able to accept input params (and there is a feature request for that here), but I think triggers are meant for situations when you'd only have a couple of transition. You wouldn't want to randomize a trigger value whenever you need to trigger an animation for the height. AnimationBuilder is the better choice for your case.
来源:https://stackoverflow.com/questions/45377870/angular-4-dynamic-height-animation-reverts-after-animation