Skip to content

Commit 1ad8452

Browse files
committed
Implement object-form keyframe syntax.
This patch extends the web-animations and web-animations-next polyfills to accept the object-form syntax for specifying keyframes (http://w3c.github.io/web-animations/#processing-a-frames-argument). The capacity is added to the base polyfill, so loading the web-animations polyfill will enable the new syntax. It is possible that a browser has a native Web Animations implementation (and hence does not load the base polyfill), but does not natively accept object-form keyframes. To address this, this patch also adds a file to the 'bonus' sources, so the object-form keyframe syntax can be loaded independently of the base polyfill.
1 parent cef7726 commit 1ad8452

7 files changed

+94
-5
lines changed

src/normalize-keyframes.js

+44-3
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,53 @@
165165
}
166166
};
167167

168-
function normalizeKeyframes(effectInput) {
169-
if (!Array.isArray(effectInput) && effectInput !== null)
170-
throw new TypeError('Keyframes must be null or an array of keyframes');
168+
function convertToArrayForm(effectInput) {
169+
var normalizedEffectInput = [];
170+
171+
for (var property in effectInput) {
172+
if (property in ['easing', 'offset', 'composite'])
173+
continue;
174+
175+
var values = effectInput[property];
176+
if (!Array.isArray(values))
177+
values = [values];
178+
179+
var keyframe;
180+
var numKeyframes = values.length;
181+
for (var i = 0; i < numKeyframes; i++) {
182+
keyframe = {};
183+
184+
if ('offset' in effectInput)
185+
keyframe['offset'] = effectInput['offset'];
186+
else if (numKeyframes == 1)
187+
keyframe['offset'] = 1.0;
188+
else
189+
keyframe['offset'] = i / (numKeyframes - 1.0);
190+
191+
if ('easing' in effectInput)
192+
keyframe['easing'] = effectInput['easing'];
193+
194+
if ('composite' in effectInput)
195+
keyframe['composite'] = effectInput['composite'];
196+
197+
keyframe[property] = values[i];
171198

199+
normalizedEffectInput.push(keyframe);
200+
}
201+
}
202+
203+
normalizedEffectInput.sort(function(a, b) { return a['offset'] - b['offset']; });
204+
return normalizedEffectInput;
205+
};
206+
207+
function normalizeKeyframes(effectInput) {
172208
if (effectInput == null)
173209
return [];
174210

211+
if (!Array.isArray(effectInput)) {
212+
effectInput = convertToArrayForm(effectInput);
213+
}
214+
175215
var keyframes = effectInput.map(function(originalKeyframe) {
176216
var keyframe = {};
177217
for (var member in originalKeyframe) {
@@ -250,6 +290,7 @@
250290
return keyframes;
251291
}
252292

293+
shared.convertToArrayForm = convertToArrayForm;
253294
shared.normalizeKeyframes = normalizeKeyframes;
254295

255296
if (WEB_ANIMATIONS_TESTING) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2016 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+
(function(shared) {
16+
// If an animation with the new syntax applies an effect, there's no need
17+
// to load this part of the polyfill.
18+
var element = document.documentElement;
19+
var player = element.animate({'left': ['10px', '20px']},
20+
{duration: 1, fill: 'forwards'});
21+
player.finish();
22+
if (getComputedStyle(element).getPropertyValue('left') == '20px')
23+
return;
24+
25+
var originalElementAnimate = window.Element.prototype.animate;
26+
window.Element.prototype.animate = function(effectInput, timingInput) {
27+
if (!Array.isArray(effectInput) && effectInput !== null)
28+
effectInput = shared.convertToArrayForm(effectInput);
29+
return originalElementAnimate.call(this, effectInput, timingInput);
30+
};
31+
})(webAnimationsShared);

target-config.js

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
var webAnimations1BonusSrc = [
4646
'src/web-animations-bonus-cancel-events.js',
47+
'src/web-animations-bonus-object-form-keyframes.js',
4748
];
4849

4950
var liteWebAnimations1Src = [

test/js/keyframes.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,22 @@ suite('keyframes', function() {
177177
});
178178

179179
test('Normalize input that is not an array.', function() {
180-
assert.throws(function() {
181-
normalizeKeyframes(10);
180+
var normalizedKeyframes;
181+
assert.doesNotThrow(function() {
182+
normalizedKeyframes = normalizeKeyframes({left: '10px'});
182183
});
184+
assert(normalizedKeyframes.length, 1);
185+
assert.equal(normalizedKeyframes[0].left, '10px');
186+
});
187+
188+
test('Normalize object-form input.', function() {
189+
var normalizedKeyframes;
190+
assert.doesNotThrow(function() {
191+
normalizedKeyframes = normalizeKeyframes({left: ['10px', '100px']});
192+
});
193+
assert(normalizedKeyframes.length, 2);
194+
assert.equal(normalizedKeyframes[0].left, '10px');
195+
assert.equal(normalizedKeyframes[1].left, '100px');
183196
});
184197

185198
test('Normalize an empty array.', function() {

web-animations-next-lite.dev.html

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
<script src="src/transform-handler.js"></script>
3737
<script src="src/property-names.js"></script>
3838
<script src="src/web-animations-bonus-cancel-events.js"></script>
39+
<script src="src/web-animations-bonus-object-form-keyframes.js"></script>
3940
<script src="src/timeline.js"></script>
4041
<script src="src/web-animations-next-animation.js"></script>
4142
<script src="src/keyframe-effect-constructor.js"></script>

web-animations-next.dev.html

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<script src="src/shape-handler.js"></script>
4242
<script src="src/property-names.js"></script>
4343
<script src="src/web-animations-bonus-cancel-events.js"></script>
44+
<script src="src/web-animations-bonus-object-form-keyframes.js"></script>
4445
<script src="src/timeline.js"></script>
4546
<script src="src/web-animations-next-animation.js"></script>
4647
<script src="src/keyframe-effect-constructor.js"></script>

web-animations.dev.html

+1
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@
4141
<script src="src/shape-handler.js"></script>
4242
<script src="src/property-names.js"></script>
4343
<script src="src/web-animations-bonus-cancel-events.js"></script>
44+
<script src="src/web-animations-bonus-object-form-keyframes.js"></script>
4445

0 commit comments

Comments
 (0)