Skip to content

Commit

Permalink
feat(animations): provide support for web-workers
Browse files Browse the repository at this point in the history
  • Loading branch information
matsko committed Nov 7, 2016
1 parent 3e91a65 commit 45cad2c
Show file tree
Hide file tree
Showing 21 changed files with 793 additions and 52 deletions.
13 changes: 9 additions & 4 deletions modules/@angular/core/src/animation/animation_group_player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import {AnimationPlayer} from './animation_player';
export class AnimationGroupPlayer implements AnimationPlayer {
private _onDoneFns: Function[] = [];
private _onStartFns: Function[] = [];
private _finished = false;
private _started = false;
private _finished: boolean = false;
private _started: boolean = false;
private _destroyed: boolean = false;

public parentPlayer: AnimationPlayer = null;

Expand Down Expand Up @@ -73,8 +74,12 @@ export class AnimationGroupPlayer implements AnimationPlayer {
}

destroy(): void {
this._onFinish();
this._players.forEach(player => player.destroy());
if (!this._destroyed) {
this._onFinish();
this._players.forEach(player => player.destroy());
this._destroyed = true;
this._players = [];
}
}

reset(): void { this._players.forEach(player => player.reset()); }
Expand Down
11 changes: 8 additions & 3 deletions modules/@angular/core/src/animation/animation_sequence_player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ export class AnimationSequencePlayer implements AnimationPlayer {
private _activePlayer: AnimationPlayer;
private _onDoneFns: Function[] = [];
private _onStartFns: Function[] = [];
private _finished = false;
private _finished: boolean = false;
private _started: boolean = false;
private _destroyed: boolean = false;

public parentPlayer: AnimationPlayer = null;

Expand Down Expand Up @@ -90,8 +91,12 @@ export class AnimationSequencePlayer implements AnimationPlayer {
}

destroy(): void {
this._onFinish();
this._players.forEach(player => player.destroy());
if (!this._destroyed) {
this._onFinish();
this._players.forEach(player => player.destroy());
this._destroyed = true;
this._activePlayer = new NoOpAnimationPlayer();
}
}

setPosition(p: any /** TODO #9100 */): void { this._players[0].setPosition(p); }
Expand Down
4 changes: 2 additions & 2 deletions modules/@angular/core/testing/mock_animation_player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {AnimationPlayer} from '@angular/core';
export class MockAnimationPlayer implements AnimationPlayer {
private _onDoneFns: Function[] = [];
private _onStartFns: Function[] = [];
private _finished = false;
private _destroyed = false;
private _finished: boolean = false;
private _destroyed: boolean = false;
private _started: boolean = false;

public parentPlayer: AnimationPlayer = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export interface DomAnimatePlayer {
onfinish: Function;
position: number;
currentTime: number;
addEventListener(eventName: string, handler: (event: any) => any): any;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import {DomAnimatePlayer} from './dom_animate_player';
export class WebAnimationsPlayer implements AnimationPlayer {
private _onDoneFns: Function[] = [];
private _onStartFns: Function[] = [];
private _finished = false;
private _initialized = false;
private _finished: boolean = false;
private _initialized: boolean = false;
private _destroyed: boolean = false;
private _player: DomAnimatePlayer;
private _started: boolean = false;
private _duration: number;
Expand Down Expand Up @@ -54,7 +55,7 @@ export class WebAnimationsPlayer implements AnimationPlayer {

// this is required so that the player doesn't start to animate right away
this.reset();
this._player.onfinish = () => this._onFinish();
this._player.addEventListener('finish', () => this._onFinish());
}

/** @internal */
Expand Down Expand Up @@ -97,8 +98,11 @@ export class WebAnimationsPlayer implements AnimationPlayer {
hasStarted(): boolean { return this._started; }

destroy(): void {
this.reset();
this._onFinish();
if (!this._destroyed) {
this.reset();
this._onFinish();
this._destroyed = true;
}
}

get totalTime(): number { return this._duration; }
Expand Down
9 changes: 5 additions & 4 deletions modules/@angular/platform-browser/src/private_export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import * as dom_events from './dom/events/dom_events';
import * as hammer_gesture from './dom/events/hammer_gestures';
import * as key_events from './dom/events/key_events';
import * as shared_styles_host from './dom/shared_styles_host';


import {WebAnimationsDriver} from './dom/web_animations_driver';

export var __platform_browser_private__: {
_BrowserPlatformLocation?: location.BrowserPlatformLocation,
Expand Down Expand Up @@ -54,7 +53,8 @@ export var __platform_browser_private__: {
HammerGesturesPlugin: typeof hammer_gesture.HammerGesturesPlugin,
initDomAdapter: typeof browser.initDomAdapter,
INTERNAL_BROWSER_PLATFORM_PROVIDERS: typeof browser.INTERNAL_BROWSER_PLATFORM_PROVIDERS,
BROWSER_SANITIZATION_PROVIDERS: typeof browser.BROWSER_SANITIZATION_PROVIDERS
BROWSER_SANITIZATION_PROVIDERS: typeof browser.BROWSER_SANITIZATION_PROVIDERS,
WebAnimationsDriver: typeof WebAnimationsDriver
} = {
BrowserPlatformLocation: location.BrowserPlatformLocation,
DomAdapter: dom_adapter.DomAdapter,
Expand All @@ -78,5 +78,6 @@ export var __platform_browser_private__: {
HammerGesturesPlugin: hammer_gesture.HammerGesturesPlugin,
initDomAdapter: browser.initDomAdapter,
INTERNAL_BROWSER_PLATFORM_PROVIDERS: browser.INTERNAL_BROWSER_PLATFORM_PROVIDERS,
BROWSER_SANITIZATION_PROVIDERS: browser.BROWSER_SANITIZATION_PROVIDERS
BROWSER_SANITIZATION_PROVIDERS: browser.BROWSER_SANITIZATION_PROVIDERS,
WebAnimationsDriver: WebAnimationsDriver
};
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,9 @@ export class MockDomAnimatePlayer implements DomAnimatePlayer {
this._position = val;
}
get position(): number { return this._position; }
addEventListener(eventName: string, handler: (event: any) => any): any {
if (eventName == 'finish') {
this.onfinish = handler;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ export const KeyEventsPlugin: typeof _.KeyEventsPlugin = _.KeyEventsPlugin;
export const HammerGesturesPlugin: typeof _.HammerGesturesPlugin = _.HammerGesturesPlugin;
export const DomAdapter: typeof _.DomAdapter = _.DomAdapter;
export const setRootDomAdapter: typeof _.setRootDomAdapter = _.setRootDomAdapter;
export const WebAnimationsDriver: typeof _.WebAnimationsDriver = _.WebAnimationsDriver;
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import {isPresent} from '../../facade/lang';
import {RenderStore} from './render_store';
import {LocationType} from './serialized_types';



// PRIMITIVE is any type that does not need to be serialized (string, number, boolean)
// We set it to String so that it is considered a Type.
/**
Expand Down Expand Up @@ -121,5 +119,6 @@ export class Serializer {
}
}

export const ANIMATION_WORKER_PLAYER_PREFIX = 'AnimationPlayer.';

export class RenderStoreObject {}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/


import {EventEmitter} from '../../facade/async';
import {RenderStoreObject, Serializer} from '../shared/serializer';

Expand All @@ -15,6 +13,15 @@ import {serializeEventWithTarget, serializeGenericEvent, serializeKeyboardEvent,
export class EventDispatcher {
constructor(private _sink: EventEmitter<any>, private _serializer: Serializer) {}

dispatchAnimationEvent(player: any, phaseName: string, element: any): boolean {
this._sink.emit({
'element': this._serializer.serialize(element, RenderStoreObject),
'animationPlayer': this._serializer.serialize(player, RenderStoreObject),
'phaseName': phaseName
});
return true;
}

dispatchRenderEvent(element: any, eventTarget: string, eventName: string, event: any): boolean {
var serializedEvent: any /** TODO #9100 */;
// TODO (jteplitz602): support custom events #3350
Expand Down
86 changes: 82 additions & 4 deletions modules/@angular/platform-webworker/src/web_workers/ui/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/

import {Injectable, RenderComponentType, Renderer, RootRenderer} from '@angular/core';

import {AnimationPlayer, Injectable, RenderComponentType, Renderer, RootRenderer} from '@angular/core';
import {MessageBus} from '../shared/message_bus';
import {EVENT_CHANNEL, RENDERER_CHANNEL} from '../shared/messaging_api';
import {RenderStore} from '../shared/render_store';
import {PRIMITIVE, RenderStoreObject, Serializer} from '../shared/serializer';
import {ServiceMessageBrokerFactory} from '../shared/service_message_broker';
import {ANIMATION_WORKER_PLAYER_PREFIX, PRIMITIVE, RenderStoreObject, Serializer} from '../shared/serializer';
import {ServiceMessageBroker, ServiceMessageBrokerFactory} from '../shared/service_message_broker';
import {EventDispatcher} from '../ui/event_dispatcher';

@Injectable()
Expand Down Expand Up @@ -86,6 +85,65 @@ export class MessageBasedRenderer {
this._listenGlobal.bind(this));
broker.registerMethod(
'listenDone', [RenderStoreObject, RenderStoreObject], this._listenDone.bind(this));
broker.registerMethod(
'animate',
[
RenderStoreObject, RenderStoreObject, PRIMITIVE, PRIMITIVE, PRIMITIVE, PRIMITIVE,
PRIMITIVE, PRIMITIVE
],
this._animate.bind(this));

this._bindAnimationPlayerMethods(broker);
}

private _bindAnimationPlayerMethods(broker: ServiceMessageBroker) {
broker.registerMethod(
ANIMATION_WORKER_PLAYER_PREFIX + 'play', [RenderStoreObject, RenderStoreObject],
(player: AnimationPlayer, element: any) => player.play());

broker.registerMethod(
ANIMATION_WORKER_PLAYER_PREFIX + 'pause', [RenderStoreObject, RenderStoreObject],
(player: AnimationPlayer, element: any) => player.pause());

broker.registerMethod(
ANIMATION_WORKER_PLAYER_PREFIX + 'init', [RenderStoreObject, RenderStoreObject],
(player: AnimationPlayer, element: any) => player.init());

broker.registerMethod(
ANIMATION_WORKER_PLAYER_PREFIX + 'restart', [RenderStoreObject, RenderStoreObject],
(player: AnimationPlayer, element: any) => player.restart());

broker.registerMethod(
ANIMATION_WORKER_PLAYER_PREFIX + 'destroy', [RenderStoreObject, RenderStoreObject],
(player: AnimationPlayer, element: any) => {
player.destroy();
this._renderStore.remove(player);
});

broker.registerMethod(
ANIMATION_WORKER_PLAYER_PREFIX + 'finish', [RenderStoreObject, RenderStoreObject],
(player: AnimationPlayer, element: any) => player.finish());

broker.registerMethod(
ANIMATION_WORKER_PLAYER_PREFIX + 'getPosition', [RenderStoreObject, RenderStoreObject],
(player: AnimationPlayer, element: any) => player.getPosition());

broker.registerMethod(
ANIMATION_WORKER_PLAYER_PREFIX + 'onStart',
[RenderStoreObject, RenderStoreObject, PRIMITIVE],
(player: AnimationPlayer, element: any) =>
this._listenOnAnimationPlayer(player, element, 'onStart'));

broker.registerMethod(
ANIMATION_WORKER_PLAYER_PREFIX + 'onDone',
[RenderStoreObject, RenderStoreObject, PRIMITIVE],
(player: AnimationPlayer, element: any) =>
this._listenOnAnimationPlayer(player, element, 'onDone'));

broker.registerMethod(
ANIMATION_WORKER_PLAYER_PREFIX + 'setPosition',
[RenderStoreObject, RenderStoreObject, PRIMITIVE],
(player: AnimationPlayer, element: any, position: number) => player.setPosition(position));
}

private _renderComponent(renderComponentType: RenderComponentType, rendererId: number) {
Expand Down Expand Up @@ -187,4 +245,24 @@ export class MessageBasedRenderer {
}

private _listenDone(renderer: Renderer, unlistenCallback: Function) { unlistenCallback(); }

private _animate(
renderer: Renderer, element: any, startingStyles: any, keyframes: any[], duration: number,
delay: number, easing: string, playerId: any) {
var player = renderer.animate(element, startingStyles, keyframes, duration, delay, easing);
this._renderStore.store(player, playerId);
}

private _listenOnAnimationPlayer(player: AnimationPlayer, element: any, phaseName: string) {
const onEventComplete =
() => { this._eventDispatcher.dispatchAnimationEvent(player, phaseName, element); };

// there is no need to register a unlistener value here since the
// internal player callbacks are removed when the player is destroyed
if (phaseName == 'onDone') {
player.onDone(() => onEventComplete());
} else {
player.onStart(() => onEventComplete());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

// no deserialization is necessary in TS.
// This is only here to match dart interface
export function deserializeGenericEvent(serializedEvent: {[key: string]: any}):
Expand Down
Loading

0 comments on commit 45cad2c

Please sign in to comment.