Skip to content

Commit

Permalink
fix(animations): evaluate substitutions on option param values
Browse files Browse the repository at this point in the history
  • Loading branch information
matsko authored and alxhub committed Jun 8, 2017
1 parent 022835b commit e9886d7
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 11 deletions.
23 changes: 12 additions & 11 deletions packages/animations/browser/src/dsl/animation_timeline_builder.ts
Expand Up @@ -199,34 +199,35 @@ export class AnimationTimelineBuilderVisitor implements AstVisitor {

visitSequence(ast: SequenceAst, context: AnimationTimelineContext) {
const subContextCount = context.subContextCount;
let ctx = context;
const options = ast.options;

if (options && (options.params || options.delay)) {
context.createSubContext(options);
context.transformIntoNewTimeline();
ctx = context.createSubContext(options);
ctx.transformIntoNewTimeline();

if (options.delay != null) {
if (context.previousNode instanceof StyleAst) {
context.currentTimeline.snapshotCurrentStyles();
context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
if (ctx.previousNode instanceof StyleAst) {
ctx.currentTimeline.snapshotCurrentStyles();
ctx.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
}

const delay = resolveTimingValue(options.delay);
context.delayNextStep(delay);
ctx.delayNextStep(delay);
}
}

if (ast.steps.length) {
ast.steps.forEach(s => s.visit(this, context));
ast.steps.forEach(s => s.visit(this, ctx));

// this is here just incase the inner steps only contain or end with a style() call
context.currentTimeline.applyStylesToKeyframe();
ctx.currentTimeline.applyStylesToKeyframe();

// this means that some animation function within the sequence
// ended up creating a sub timeline (which means the current
// timeline cannot overlap with the contents of the sequence)
if (context.subContextCount > subContextCount) {
context.transformIntoNewTimeline();
if (ctx.subContextCount > subContextCount) {
ctx.transformIntoNewTimeline();
}
}

Expand Down Expand Up @@ -475,7 +476,7 @@ export class AnimationTimelineContext {

Object.keys(newParams).forEach(name => {
if (!skipIfExists || !paramsToUpdate.hasOwnProperty(name)) {
paramsToUpdate[name] = newParams[name];
paramsToUpdate[name] = interpolateParams(newParams[name], paramsToUpdate, this.errors);
}
});
}
Expand Down
50 changes: 50 additions & 0 deletions packages/animations/browser/test/dsl/animation_spec.ts
Expand Up @@ -358,6 +358,56 @@ export function main() {
]);
});

it('should substitute in values that are defined as parameters for inner areas of a sequence',
() => {
const steps = sequence(
[
sequence(
[
sequence(
[
style({height: '{{ x0 }}px'}),
animate(1000, style({height: '{{ x2 }}px'})),
],
buildParams({x2: '{{ x1 }}3'})),
],
buildParams({x1: '{{ x0 }}2'})),
],
buildParams({x0: '1'}));

const players = invokeAnimationSequence(rootElement, steps);
expect(players.length).toEqual(1);
const [player] = players;
expect(player.keyframes).toEqual([
{offset: 0, height: '1px'}, {offset: 1, height: '123px'}
]);
});

it('should substitute in values that are defined as parameters for reusable animations',
() => {
const anim = animation([
style({height: '{{ start }}'}),
animate(1000, style({height: '{{ end }}'})),
]);

const steps = sequence(
[
sequence(
[
useAnimation(anim, buildParams({start: '{{ a }}', end: '{{ b }}'})),
],
buildParams({a: '100px', b: '200px'})),
],
buildParams({a: '0px'}));

const players = invokeAnimationSequence(rootElement, steps);
expect(players.length).toEqual(1);
const [player] = players;
expect(player.keyframes).toEqual([
{offset: 0, height: '100px'}, {offset: 1, height: '200px'}
]);
});

it('should throw an error when an input variable is not provided when invoked and is not a default value',
() => {
expect(() => {invokeAnimationSequence(rootElement, [style({color: '{{ color }}'})])})
Expand Down

0 comments on commit e9886d7

Please sign in to comment.