• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5//     You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//     See the License for the specific language governing permissions and
13// limitations under the License.
14
15
16(function(shared, scope, testing) {
17  var originalRequestAnimationFrame = window.requestAnimationFrame;
18  window.requestAnimationFrame = function(f) {
19    return originalRequestAnimationFrame(function(x) {
20      scope.timeline._updateAnimationsPromises();
21      f(x);
22      scope.timeline._updateAnimationsPromises();
23    });
24  };
25
26  scope.AnimationTimeline = function() {
27    this._animations = [];
28    this.currentTime = undefined;
29  };
30
31  scope.AnimationTimeline.prototype = {
32    getAnimations: function() {
33      this._discardAnimations();
34      return this._animations.slice();
35    },
36    _updateAnimationsPromises: function() {
37      scope.animationsWithPromises = scope.animationsWithPromises.filter(function(animation) {
38        return animation._updatePromises();
39      });
40    },
41    _discardAnimations: function() {
42      this._updateAnimationsPromises();
43      this._animations = this._animations.filter(function(animation) {
44        return animation.playState != 'finished' && animation.playState != 'idle';
45      });
46    },
47    _play: function(effect) {
48      var animation = new scope.Animation(effect, this);
49      this._animations.push(animation);
50      scope.restartWebAnimationsNextTick();
51      // Use animation._animation.play() here, NOT animation.play().
52      //
53      // Timeline.play calls new scope.Animation(effect) which (indirectly) calls Timeline.play on
54      // effect's children, and Animation.play is also recursive. We only need to call play on each
55      // animation in the tree once.
56      animation._updatePromises();
57      animation._animation.play();
58      animation._updatePromises();
59      return animation;
60    },
61    play: function(effect) {
62      if (effect) {
63        effect.remove();
64      }
65      return this._play(effect);
66    }
67  };
68
69  var ticking = false;
70
71  scope.restartWebAnimationsNextTick = function() {
72    if (!ticking) {
73      ticking = true;
74      requestAnimationFrame(webAnimationsNextTick);
75    }
76  };
77
78  function webAnimationsNextTick(t) {
79    var timeline = scope.timeline;
80    timeline.currentTime = t;
81    timeline._discardAnimations();
82    if (timeline._animations.length == 0)
83      ticking = false;
84    else
85      requestAnimationFrame(webAnimationsNextTick);
86  }
87
88  var timeline = new scope.AnimationTimeline();
89  scope.timeline = timeline;
90
91  try {
92    Object.defineProperty(window.document, 'timeline', {
93      configurable: true,
94      get: function() { return timeline; }
95    });
96  } catch (e) { }
97  try {
98    window.document.timeline = timeline;
99  } catch (e) { }
100
101})(webAnimationsShared, webAnimationsNext, webAnimationsTesting);
102