diff --git a/packages/animations/browser/src/dsl/animation_timeline_builder.ts b/packages/animations/browser/src/dsl/animation_timeline_builder.ts
index b4cf46b4dc7d4..e4e9b90bddea2 100644
--- a/packages/animations/browser/src/dsl/animation_timeline_builder.ts
+++ b/packages/animations/browser/src/dsl/animation_timeline_builder.ts
@@ -183,32 +183,25 @@ export class AnimationTimelineBuilderVisitor implements AstVisitor {
visitAnimateRef(ast: AnimateRefAst, context: AnimationTimelineContext): any {
const innerContext = context.createSubContext(ast.options);
innerContext.transformIntoNewTimeline();
- this._applyAnimateRefDelay(ast.animation, context, innerContext);
+ this._applyAnimationRefDelays([ast.options, ast.animation.options], context, innerContext);
this.visitReference(ast.animation, innerContext);
context.transformIntoNewTimeline(innerContext.currentTimeline.currentTime);
context.previousNode = ast;
}
- private _applyAnimateRefDelay(
- animation: ReferenceAst, context: AnimationTimelineContext,
+ private _applyAnimationRefDelays(
+ animationsRefsOptions: (AnimationOptions|null)[], context: AnimationTimelineContext,
innerContext: AnimationTimelineContext) {
- const animationDelay = animation.options?.delay;
-
- if (!animationDelay) {
- return;
- }
-
- let animationDelayValue: number;
-
- if (typeof animationDelay === 'string') {
- const interpolatedDelay =
- interpolateParams(animationDelay, animation.options?.params ?? {}, context.errors);
- animationDelayValue = resolveTimingValue(interpolatedDelay);
- } else {
- animationDelayValue = animationDelay;
+ for (const animationRefOptions of animationsRefsOptions) {
+ const animationDelay = animationRefOptions?.delay;
+ if (animationDelay) {
+ const animationDelayValue = typeof animationDelay === 'number' ?
+ animationDelay :
+ resolveTimingValue(interpolateParams(
+ animationDelay, animationRefOptions?.params ?? {}, context.errors));
+ innerContext.delayNextStep(animationDelayValue);
+ }
}
-
- innerContext.delayNextStep(animationDelayValue);
}
private _visitSubInstructions(
diff --git a/packages/core/test/animation/animation_integration_spec.ts b/packages/core/test/animation/animation_integration_spec.ts
index be15eafcf5054..aba0ad4119a49 100644
--- a/packages/core/test/animation/animation_integration_spec.ts
+++ b/packages/core/test/animation/animation_integration_spec.ts
@@ -3923,13 +3923,57 @@ describe('animation tests', function() {
]);
});
- it('should combine the delay specified in the animation with that of the caller', () => {
+ it('should apply the delay specified in the useAnimation call', () => {
+ const animationMetaData = animation([
+ style({color: 'red'}),
+ animate(550, style({color: 'green'})),
+ ]);
+
+ @Component({
+ selector: 'cmp',
+ template: `
+
+
+ `,
+ animations: [
+ trigger('anim', [transition(
+ ':enter',
+ useAnimation(animationMetaData, {delay: 1500}),
+ )]),
+ ]
+ })
+ class Cmp {
+ exp: boolean = false;
+ }
+
+ TestBed.configureTestingModule({declarations: [Cmp]});
+
+ const engine = TestBed.inject(ɵAnimationEngine);
+ const fixture = TestBed.createComponent(Cmp);
+ const cmp = fixture.componentInstance;
+ cmp.exp = true;
+
+ fixture.detectChanges();
+ engine.flush();
+
+ const players = getLog();
+ expect(players.length).toEqual(1);
+ const [player] = players;
+ expect(player.delay).toEqual(1500);
+ expect(player.duration).toEqual(550);
+ expect(player.keyframes).toEqual([
+ new Map([['color', 'red'], ['offset', 0]]),
+ new Map([['color', 'green'], ['offset', 1]]),
+ ]);
+ });
+
+ it('should apply the delay specified in the useAnimation call using params', () => {
const animationMetaData = animation(
[
style({color: 'red'}),
- animate(500, style({color: 'green'})),
+ animate(700, style({color: 'green'})),
],
- {delay: 2000});
+ );
@Component({
selector: 'cmp',
@@ -3938,7 +3982,13 @@ describe('animation tests', function() {
`,
animations: [
- trigger('anim', [transition(':enter', useAnimation(animationMetaData), {delay: 750})]),
+ trigger('anim', [transition(
+ ':enter',
+ useAnimation(animationMetaData, {
+ delay: '{{useAnimationDelay}}ms',
+ params: {useAnimationDelay: 7500}
+ }),
+ )]),
]
})
class Cmp {
@@ -3958,13 +4008,59 @@ describe('animation tests', function() {
const players = getLog();
expect(players.length).toEqual(1);
const [player] = players;
- expect(player.delay).toEqual(2750);
- expect(player.duration).toEqual(500);
+ expect(player.delay).toEqual(7500);
+ expect(player.duration).toEqual(700);
expect(player.keyframes).toEqual([
new Map([['color', 'red'], ['offset', 0]]),
new Map([['color', 'green'], ['offset', 1]]),
]);
});
+
+ it('should combine the delays specified in the animation and the useAnimation with that of the caller',
+ () => {
+ const animationMetaData = animation(
+ [
+ style({color: 'red'}),
+ animate(567, style({color: 'green'})),
+ ],
+ {delay: 1000});
+
+ @Component({
+ selector: 'cmp',
+ template: `
+
+
+ `,
+ animations: [
+ trigger('anim', [transition(
+ ':enter', useAnimation(animationMetaData, {delay: 34}),
+ {delay: 200})]),
+ ]
+ })
+ class Cmp {
+ exp: boolean = false;
+ }
+
+ TestBed.configureTestingModule({declarations: [Cmp]});
+
+ const engine = TestBed.inject(ɵAnimationEngine);
+ const fixture = TestBed.createComponent(Cmp);
+ const cmp = fixture.componentInstance;
+ cmp.exp = true;
+
+ fixture.detectChanges();
+ engine.flush();
+
+ const players = getLog();
+ expect(players.length).toEqual(1);
+ const [player] = players;
+ expect(player.delay).toEqual(1234);
+ expect(player.duration).toEqual(567);
+ expect(player.keyframes).toEqual([
+ new Map([['color', 'red'], ['offset', 0]]),
+ new Map([['color', 'green'], ['offset', 1]]),
+ ]);
+ });
});
it('should combine multiple errors together into one exception when an animation fails to be built',