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(function(shared, scope, testing) { 16 17 scope.convertEffectInput = function(effectInput) { 18 var keyframes = shared.normalizeKeyframes(effectInput); 19 var propertySpecificKeyframeGroups = makePropertySpecificKeyframeGroups(keyframes); 20 var interpolations = makeInterpolations(propertySpecificKeyframeGroups); 21 return function(target, fraction) { 22 if (fraction != null) { 23 interpolations.filter(function(interpolation) { 24 return fraction >= interpolation.applyFrom && fraction < interpolation.applyTo; 25 }).forEach(function(interpolation) { 26 var offsetFraction = fraction - interpolation.startOffset; 27 var localDuration = interpolation.endOffset - interpolation.startOffset; 28 var scaledLocalTime = localDuration == 0 ? 0 : interpolation.easingFunction(offsetFraction / localDuration); 29 scope.apply(target, interpolation.property, interpolation.interpolation(scaledLocalTime)); 30 }); 31 } else { 32 for (var property in propertySpecificKeyframeGroups) 33 if (property != 'offset' && property != 'easing' && property != 'composite') 34 scope.clear(target, property); 35 } 36 }; 37 }; 38 39 40 function makePropertySpecificKeyframeGroups(keyframes) { 41 var propertySpecificKeyframeGroups = {}; 42 43 for (var i = 0; i < keyframes.length; i++) { 44 for (var member in keyframes[i]) { 45 if (member != 'offset' && member != 'easing' && member != 'composite') { 46 var propertySpecificKeyframe = { 47 offset: keyframes[i].offset, 48 easing: keyframes[i].easing, 49 value: keyframes[i][member] 50 }; 51 propertySpecificKeyframeGroups[member] = propertySpecificKeyframeGroups[member] || []; 52 propertySpecificKeyframeGroups[member].push(propertySpecificKeyframe); 53 } 54 } 55 } 56 57 for (var groupName in propertySpecificKeyframeGroups) { 58 var group = propertySpecificKeyframeGroups[groupName]; 59 if (group[0].offset != 0 || group[group.length - 1].offset != 1) { 60 throw { 61 type: DOMException.NOT_SUPPORTED_ERR, 62 name: 'NotSupportedError', 63 message: 'Partial keyframes are not supported' 64 }; 65 } 66 } 67 return propertySpecificKeyframeGroups; 68 } 69 70 71 function makeInterpolations(propertySpecificKeyframeGroups) { 72 var interpolations = []; 73 for (var groupName in propertySpecificKeyframeGroups) { 74 var keyframes = propertySpecificKeyframeGroups[groupName]; 75 for (var i = 0; i < keyframes.length - 1; i++) { 76 var startIndex = i; 77 var endIndex = i + 1; 78 var startOffset = keyframes[startIndex].offset; 79 var endOffset = keyframes[endIndex].offset; 80 var applyFrom = startOffset; 81 var applyTo = endOffset; 82 83 if (i == 0) { 84 applyFrom = -Infinity; 85 WEB_ANIMATIONS_TESTING && console.assert(startOffset == 0); 86 if (endOffset == 0) { 87 endIndex = startIndex; 88 } 89 } 90 if (i == keyframes.length - 2) { 91 applyTo = Infinity; 92 WEB_ANIMATIONS_TESTING && console.assert(endOffset == 1); 93 if (startOffset == 1) { 94 startIndex = endIndex; 95 } 96 } 97 98 interpolations.push({ 99 applyFrom: applyFrom, 100 applyTo: applyTo, 101 startOffset: keyframes[startIndex].offset, 102 endOffset: keyframes[endIndex].offset, 103 easingFunction: shared.parseEasingFunction(keyframes[startIndex].easing), 104 property: groupName, 105 interpolation: scope.propertyInterpolation(groupName, 106 keyframes[startIndex].value, 107 keyframes[endIndex].value) 108 }); 109 } 110 } 111 interpolations.sort(function(leftInterpolation, rightInterpolation) { 112 return leftInterpolation.startOffset - rightInterpolation.startOffset; 113 }); 114 return interpolations; 115 } 116 117 118 if (WEB_ANIMATIONS_TESTING) { 119 testing.makePropertySpecificKeyframeGroups = makePropertySpecificKeyframeGroups; 120 testing.makeInterpolations = makeInterpolations; 121 } 122 123})(webAnimationsShared, webAnimations1, webAnimationsTesting); 124