• 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(function(shared, scope, testing) {
15
16  var nullTarget = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
17
18  var sequenceNumber = 0;
19  scope.bindAnimationForCustomEffect = function(animation) {
20    var target = animation.effect.target;
21    var effectFunction;
22    var isKeyframeEffect = typeof animation.effect.getFrames() == 'function';
23    if (isKeyframeEffect) {
24      effectFunction = animation.effect.getFrames();
25    } else {
26      effectFunction = animation.effect._onsample;
27    }
28    var timing = animation.effect.timing;
29    var last = null;
30    timing = shared.normalizeTimingInput(timing);
31    var callback = function() {
32      var t = callback._animation ? callback._animation.currentTime : null;
33      if (t !== null) {
34        t = shared.calculateIterationProgress(shared.calculateActiveDuration(timing), t, timing);
35        if (isNaN(t))
36          t = null;
37      }
38      // FIXME: There are actually more conditions under which the effectFunction
39      // should be called.
40      if (t !== last) {
41        if (isKeyframeEffect) {
42          effectFunction(t, target, animation.effect);
43        } else {
44          effectFunction(t, animation.effect, animation.effect._animation);
45        }
46      }
47      last = t;
48    };
49
50    callback._animation = animation;
51    callback._registered = false;
52    callback._sequenceNumber = sequenceNumber++;
53    animation._callback = callback;
54    register(callback);
55  };
56
57  var callbacks = [];
58  var ticking = false;
59  function register(callback) {
60    if (callback._registered)
61      return;
62    callback._registered = true;
63    callbacks.push(callback);
64    if (!ticking) {
65      ticking = true;
66      requestAnimationFrame(tick);
67    }
68  }
69
70  function tick(t) {
71    var updating = callbacks;
72    callbacks = [];
73    updating.sort(function(left, right) {
74      return left._sequenceNumber - right._sequenceNumber;
75    });
76    updating = updating.filter(function(callback) {
77      callback();
78      var playState = callback._animation ? callback._animation.playState : 'idle';
79      if (playState != 'running' && playState != 'pending')
80        callback._registered = false;
81      return callback._registered;
82    });
83    callbacks.push.apply(callbacks, updating);
84
85    if (callbacks.length) {
86      ticking = true;
87      requestAnimationFrame(tick);
88    } else {
89      ticking = false;
90    }
91  }
92
93  scope.Animation.prototype._register = function() {
94    if (this._callback)
95      register(this._callback);
96  };
97
98})(webAnimationsShared, webAnimationsNext, webAnimationsTesting);
99