Skip to content

Commit 4577b7c

Browse files
committed
refactor(animations): introduce @angular/animation module
1 parent b988733 commit 4577b7c

File tree

56 files changed

+3980
-18
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+3980
-18
lines changed

build.sh

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ PACKAGES=(core
1313
platform-server
1414
platform-webworker
1515
platform-webworker-dynamic
16+
animation
1617
http
1718
upgrade
1819
router

modules/@angular/animation/index.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
/**
10+
* @module
11+
* @description
12+
* Entry point for all public APIs of the animation package.
13+
*/
14+
export * from './src/animation';
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "@angular/animation",
3+
"version": "0.0.0-PLACEHOLDER",
4+
"description": "Angular - animation integration with web-animations",
5+
"main": "bundles/animation.umd.js",
6+
"module": "index.js",
7+
"typings": "index.d.ts",
8+
"author": "angular",
9+
"license": "MIT",
10+
"peerDependencies": {
11+
"@angular/core": "0.0.0-PLACEHOLDER"
12+
},
13+
"repository": {
14+
"type": "git",
15+
"url": "https://github.com/angular/angular.git"
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
export default {
10+
entry: '../../../dist/packages-dist/animation/testing/index.js',
11+
dest: '../../../dist/packages-dist/animation/bundles/animation-testing.umd.js',
12+
format: 'umd',
13+
moduleName: 'ng.animation.testing',
14+
globals: {
15+
'@angular/core': 'ng.core',
16+
'@angular/animation': 'ng.animation',
17+
'rxjs/Observable': 'Rx',
18+
'rxjs/Subject': 'Rx'
19+
}
20+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
export default {
10+
entry: '../../../dist/packages-dist/animation/index.js',
11+
dest: '../../../dist/packages-dist/animation/bundles/animation.umd.js',
12+
format: 'umd',
13+
moduleName: 'ng.animation',
14+
globals: {
15+
'@angular/core': 'ng.core',
16+
'rxjs/Observable': 'Rx',
17+
'rxjs/Subject': 'Rx',
18+
}
19+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
export {AnimationModule} from './animation_module';
9+
export {Animation} from './dsl/animation';
10+
export {AUTO_STYLE, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationSequenceMetadata, AnimationStateMetadata, AnimationStyleMetadata, AnimationTransitionMetadata, animate, group, keyframes, sequence, state, style, transition} from './dsl/animation_metadata';
11+
export {AnimationTrigger, trigger} from './dsl/animation_trigger';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import {NgModule} from '@angular/core';
9+
import {AnimationStyleNormalizer} from './dsl/style_normalization/animation_style_normalizer';
10+
import {WebAnimationsStyleNormalizer} from './dsl/style_normalization/web_animations_style_normalizer';
11+
import {AnimationDriver, NoOpAnimationDriver} from './engine/animation_driver';
12+
import {DomAnimationTransitionEngine} from './engine/dom_animation_transition_engine';
13+
import {WebAnimationsDriver, supportsWebAnimations} from './engine/web_animations/web_animations_driver';
14+
import {TransitionEngine} from './private_import_core';
15+
16+
export function resolveDefaultAnimationDriver(): AnimationDriver {
17+
if (supportsWebAnimations()) {
18+
return new WebAnimationsDriver();
19+
}
20+
return new NoOpAnimationDriver();
21+
}
22+
23+
/**
24+
* The module that includes all animation code such as `style()`, `animate()`, `trigger()`, etc...
25+
*
26+
* @experimental
27+
*/
28+
@NgModule({
29+
providers: [
30+
{provide: AnimationDriver, useFactory: resolveDefaultAnimationDriver},
31+
{provide: AnimationStyleNormalizer, useClass: WebAnimationsStyleNormalizer},
32+
{provide: TransitionEngine, useClass: DomAnimationTransitionEngine}
33+
]
34+
})
35+
export class AnimationModule {
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
export interface StyleData { [key: string]: string|number; }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import {AnimationStyles} from '@angular/core';
9+
import {AnimateTimings} from './../dsl/animation_metadata';
10+
import {StyleData} from './style_data';
11+
12+
export const ONE_SECOND = 1000;
13+
14+
export function parseTimeExpression(exp: string | number, errors: string[]): AnimateTimings {
15+
const regex = /^([\.\d]+)(m?s)(?:\s+([\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?$/i;
16+
let duration: number;
17+
let delay: number = 0;
18+
let easing: string = null;
19+
if (typeof exp === 'string') {
20+
const matches = exp.match(regex);
21+
if (matches === null) {
22+
errors.push(`The provided timing value "${exp}" is invalid.`);
23+
return {duration: 0, delay: 0, easing: null};
24+
}
25+
26+
let durationMatch = parseFloat(matches[1]);
27+
const durationUnit = matches[2];
28+
if (durationUnit == 's') {
29+
durationMatch *= ONE_SECOND;
30+
}
31+
duration = Math.floor(durationMatch);
32+
33+
const delayMatch = matches[3];
34+
const delayUnit = matches[4];
35+
if (delayMatch != null) {
36+
let delayVal: number = parseFloat(delayMatch);
37+
if (delayUnit != null && delayUnit == 's') {
38+
delayVal *= ONE_SECOND;
39+
}
40+
delay = Math.floor(delayVal);
41+
}
42+
43+
const easingVal = matches[5];
44+
if (easingVal) {
45+
easing = easingVal;
46+
}
47+
} else {
48+
duration = <number>exp;
49+
}
50+
51+
return {duration, delay, easing};
52+
}
53+
54+
export function normalizeStyles(styles: AnimationStyles): StyleData {
55+
const normalizedStyles: StyleData = {};
56+
styles.styles.forEach((styleMap: any) => copyStyles(styleMap, false, normalizedStyles));
57+
return normalizedStyles;
58+
}
59+
60+
export function copyStyles(
61+
styles: StyleData, readPrototype: boolean, destination: StyleData = {}): StyleData {
62+
if (readPrototype) {
63+
// we make use of a for-in loop so that the
64+
// prototypically inherited properties are
65+
// revealed from the backFill map
66+
for (let prop in styles) {
67+
destination[prop] = styles[prop];
68+
}
69+
} else {
70+
Object.keys(styles).forEach(prop => destination[prop] = styles[prop]);
71+
}
72+
return destination;
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import {AnimationPlayer, AnimationStyles, Injector} from '@angular/core';
9+
import {StyleData} from '../common/style_data';
10+
import {normalizeStyles} from '../common/util';
11+
import {AnimationDriver} from '../engine/animation_driver';
12+
import {DomAnimationTransitionEngine} from '../engine/dom_animation_transition_engine';
13+
import {AnimationMetadata, sequence} from './animation_metadata';
14+
import {AnimationTimelineInstruction} from './animation_timeline_instruction';
15+
import {buildAnimationKeyframes} from './animation_timeline_visitor';
16+
import {validateAnimationSequence} from './animation_validator_visitor';
17+
import {AnimationStyleNormalizer} from './style_normalization/animation_style_normalizer';
18+
19+
/**
20+
* @experimental Animation support is experimental.
21+
*/
22+
export class Animation {
23+
private _animationAst: AnimationMetadata;
24+
constructor(input: AnimationMetadata|AnimationMetadata[]) {
25+
const ast =
26+
Array.isArray(input) ? sequence(<AnimationMetadata[]>input) : <AnimationMetadata>input;
27+
const errors = validateAnimationSequence(ast);
28+
if (errors.length) {
29+
const errorMessage = `animation validation failed:\n${errors.join("\n")}`;
30+
throw new Error(errorMessage);
31+
}
32+
this._animationAst = ast;
33+
}
34+
35+
buildTimelines(startingStyles: StyleData|StyleData[], destinationStyles: StyleData|StyleData[]):
36+
AnimationTimelineInstruction[] {
37+
const start = Array.isArray(startingStyles) ?
38+
normalizeStyles(new AnimationStyles(<StyleData[]>startingStyles)) :
39+
<StyleData>startingStyles;
40+
const dest = Array.isArray(destinationStyles) ?
41+
normalizeStyles(new AnimationStyles(<StyleData[]>destinationStyles)) :
42+
<StyleData>destinationStyles;
43+
return buildAnimationKeyframes(this._animationAst, start, dest);
44+
}
45+
46+
// this is only used for development demo purposes for now
47+
private create(
48+
injector: Injector, element: any, startingStyles: StyleData = {},
49+
destinationStyles: StyleData = {}): AnimationPlayer {
50+
const instructions = this.buildTimelines(startingStyles, destinationStyles);
51+
52+
// note the code below is only here to make the tests happy (once the new renderer is
53+
// within core then the code below will interact with Renderer.transition(...))
54+
const driver: AnimationDriver = injector.get(AnimationDriver);
55+
const normalizer: AnimationStyleNormalizer = injector.get(AnimationStyleNormalizer);
56+
const engine = new DomAnimationTransitionEngine(driver, normalizer);
57+
return engine.process(element, instructions);
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import * as meta from './animation_metadata';
9+
10+
export interface AnimationDslVisitor {
11+
visitState(ast: meta.AnimationStateMetadata, context: any): any;
12+
visitTransition(ast: meta.AnimationTransitionMetadata, context: any): any;
13+
visitSequence(ast: meta.AnimationSequenceMetadata, context: any): any;
14+
visitGroup(ast: meta.AnimationGroupMetadata, context: any): any;
15+
visitAnimate(ast: meta.AnimationAnimateMetadata, context: any): any;
16+
visitStyle(ast: meta.AnimationStyleMetadata, context: any): any;
17+
visitKeyframeSequence(ast: meta.AnimationKeyframesSequenceMetadata, context: any): any;
18+
}
19+
20+
export function visitAnimationNode(
21+
visitor: AnimationDslVisitor, node: meta.AnimationMetadata, context: any) {
22+
switch (node.type) {
23+
case meta.AnimationMetadataType.State:
24+
return visitor.visitState(<meta.AnimationStateMetadata>node, context);
25+
case meta.AnimationMetadataType.Transition:
26+
return visitor.visitTransition(<meta.AnimationTransitionMetadata>node, context);
27+
case meta.AnimationMetadataType.Sequence:
28+
return visitor.visitSequence(<meta.AnimationSequenceMetadata>node, context);
29+
case meta.AnimationMetadataType.Group:
30+
return visitor.visitGroup(<meta.AnimationGroupMetadata>node, context);
31+
case meta.AnimationMetadataType.Animate:
32+
return visitor.visitAnimate(<meta.AnimationAnimateMetadata>node, context);
33+
case meta.AnimationMetadataType.KeyframeSequence:
34+
return visitor.visitKeyframeSequence(<meta.AnimationKeyframesSequenceMetadata>node, context);
35+
case meta.AnimationMetadataType.Style:
36+
return visitor.visitStyle(<meta.AnimationStyleMetadata>node, context);
37+
default:
38+
throw new Error(`Unable to resolve animation metadata node #${node.type}`);
39+
}
40+
}

0 commit comments

Comments
 (0)