|
39 | 39 | rafCallbacks = [];
|
40 | 40 | if (t < timeline.currentTime)
|
41 | 41 | t = timeline.currentTime;
|
42 |
| - tick(t, true); |
| 42 | + timeline._animations.sort(compareAnimations); |
| 43 | + timeline._animations = tick(t, true, timeline._animations)[0]; |
43 | 44 | processing.forEach(function(entry) { entry[1](t); });
|
44 | 45 | applyPendingEffects();
|
45 | 46 | _now = undefined;
|
|
63 | 64 | animation._timeline = this;
|
64 | 65 | this._animations.push(animation);
|
65 | 66 | scope.restart();
|
66 |
| - scope.invalidateEffects(); |
| 67 | + scope.applyDirtiedAnimation(animation); |
67 | 68 | return animation;
|
68 | 69 | }
|
69 | 70 | };
|
|
92 | 93 | return hasRestartedThisFrame;
|
93 | 94 | };
|
94 | 95 |
|
95 |
| - scope.invalidateEffects = function() { |
96 |
| - tick(scope.timeline.currentTime, false); |
| 96 | + // RAF is supposed to be the last script to occur before frame rendering but not |
| 97 | + // all browsers behave like this. This function is for synchonously updating an |
| 98 | + // animation's effects whenever its state is mutated by script to work around |
| 99 | + // incorrect script execution ordering by the browser. |
| 100 | + scope.applyDirtiedAnimation = function(animation) { |
| 101 | + if (inTick) { |
| 102 | + return; |
| 103 | + } |
| 104 | + animation._markTarget(); |
| 105 | + var animations = animation._targetAnimations(); |
| 106 | + animations.sort(compareAnimations); |
| 107 | + var inactiveAnimations = tick(scope.timeline.currentTime, false, animations.slice())[1]; |
| 108 | + inactiveAnimations.forEach(function(animation) { |
| 109 | + var index = timeline._animations.indexOf(animation); |
| 110 | + if (index !== -1) { |
| 111 | + timeline._animations.splice(index, 1); |
| 112 | + } |
| 113 | + }); |
97 | 114 | applyPendingEffects();
|
98 | 115 | };
|
99 | 116 |
|
|
105 | 122 |
|
106 | 123 | var t60hz = 1000 / 60;
|
107 | 124 |
|
108 |
| - function tick(t, isAnimationFrame) { |
| 125 | + var inTick = false; |
| 126 | + function tick(t, isAnimationFrame, updatingAnimations) { |
| 127 | + inTick = true; |
109 | 128 | hasRestartedThisFrame = false;
|
110 | 129 | var timeline = scope.timeline;
|
| 130 | + |
111 | 131 | timeline.currentTime = t;
|
112 |
| - timeline._animations.sort(compareAnimations); |
113 | 132 | ticking = false;
|
114 |
| - var updatingAnimations = timeline._animations; |
115 |
| - timeline._animations = []; |
116 | 133 |
|
117 | 134 | var newPendingClears = [];
|
118 | 135 | var newPendingEffects = [];
|
119 |
| - updatingAnimations = updatingAnimations.filter(function(animation) { |
| 136 | + var activeAnimations = []; |
| 137 | + var inactiveAnimations = []; |
| 138 | + updatingAnimations.forEach(function(animation) { |
120 | 139 | animation._tick(t, isAnimationFrame);
|
121 | 140 |
|
122 |
| - if (!animation._inEffect) |
| 141 | + if (!animation._inEffect) { |
123 | 142 | newPendingClears.push(animation._effect);
|
124 |
| - else |
| 143 | + animation._unmarkTarget(); |
| 144 | + } else { |
125 | 145 | newPendingEffects.push(animation._effect);
|
| 146 | + animation._markTarget(); |
| 147 | + } |
126 | 148 |
|
127 | 149 | if (animation._needsTick)
|
128 | 150 | ticking = true;
|
129 | 151 |
|
130 | 152 | var alive = animation._inEffect || animation._needsTick;
|
131 | 153 | animation._inTimeline = alive;
|
132 |
| - return alive; |
| 154 | + if (alive) { |
| 155 | + activeAnimations.push(animation); |
| 156 | + } else { |
| 157 | + inactiveAnimations.push(animation); |
| 158 | + } |
133 | 159 | });
|
134 | 160 |
|
135 | 161 | // FIXME: Should remove dupliactes from pendingEffects.
|
136 | 162 | pendingEffects.push.apply(pendingEffects, newPendingClears);
|
137 | 163 | pendingEffects.push.apply(pendingEffects, newPendingEffects);
|
138 | 164 |
|
139 |
| - timeline._animations.push.apply(timeline._animations, updatingAnimations); |
140 |
| - |
141 | 165 | if (ticking)
|
142 | 166 | requestAnimationFrame(function() {});
|
| 167 | + |
| 168 | + inTick = false; |
| 169 | + return [activeAnimations, inactiveAnimations]; |
143 | 170 | };
|
144 | 171 |
|
145 | 172 | if (WEB_ANIMATIONS_TESTING) {
|
|
0 commit comments