1<!-- 2@license 3Copyright (c) 2015 The Polymer Project Authors. All rights reserved. 4This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 5The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 6The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 7Code distributed by Google as part of the polymer project is also 8subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 9--> 10 11<link rel="import" href="../polymer/polymer.html"> 12 13<script> 14 15 /** 16 * `Polymer.NeonAnimatableBehavior` is implemented by elements containing animations for use with 17 * elements implementing `Polymer.NeonAnimationRunnerBehavior`. 18 * @polymerBehavior 19 */ 20 Polymer.NeonAnimatableBehavior = { 21 22 properties: { 23 24 /** 25 * Animation configuration. See README for more info. 26 */ 27 animationConfig: { 28 type: Object 29 }, 30 31 /** 32 * Convenience property for setting an 'entry' animation. Do not set `animationConfig.entry` 33 * manually if using this. The animated node is set to `this` if using this property. 34 */ 35 entryAnimation: { 36 observer: '_entryAnimationChanged', 37 type: String 38 }, 39 40 /** 41 * Convenience property for setting an 'exit' animation. Do not set `animationConfig.exit` 42 * manually if using this. The animated node is set to `this` if using this property. 43 */ 44 exitAnimation: { 45 observer: '_exitAnimationChanged', 46 type: String 47 } 48 49 }, 50 51 _entryAnimationChanged: function() { 52 this.animationConfig = this.animationConfig || {}; 53 this.animationConfig['entry'] = [{ 54 name: this.entryAnimation, 55 node: this 56 }]; 57 }, 58 59 _exitAnimationChanged: function() { 60 this.animationConfig = this.animationConfig || {}; 61 this.animationConfig['exit'] = [{ 62 name: this.exitAnimation, 63 node: this 64 }]; 65 }, 66 67 _copyProperties: function(config1, config2) { 68 // shallowly copy properties from config2 to config1 69 for (var property in config2) { 70 config1[property] = config2[property]; 71 } 72 }, 73 74 _cloneConfig: function(config) { 75 var clone = { 76 isClone: true 77 }; 78 this._copyProperties(clone, config); 79 return clone; 80 }, 81 82 _getAnimationConfigRecursive: function(type, map, allConfigs) { 83 if (!this.animationConfig) { 84 return; 85 } 86 87 if(this.animationConfig.value && typeof this.animationConfig.value === 'function') { 88 this._warn(this._logf('playAnimation', "Please put 'animationConfig' inside of your components 'properties' object instead of outside of it.")); 89 return; 90 } 91 92 // type is optional 93 var thisConfig; 94 if (type) { 95 thisConfig = this.animationConfig[type]; 96 } else { 97 thisConfig = this.animationConfig; 98 } 99 100 if (!Array.isArray(thisConfig)) { 101 thisConfig = [thisConfig]; 102 } 103 104 // iterate animations and recurse to process configurations from child nodes 105 if (thisConfig) { 106 for (var config, index = 0; config = thisConfig[index]; index++) { 107 if (config.animatable) { 108 config.animatable._getAnimationConfigRecursive(config.type || type, map, allConfigs); 109 } else { 110 if (config.id) { 111 var cachedConfig = map[config.id]; 112 if (cachedConfig) { 113 // merge configurations with the same id, making a clone lazily 114 if (!cachedConfig.isClone) { 115 map[config.id] = this._cloneConfig(cachedConfig) 116 cachedConfig = map[config.id]; 117 } 118 this._copyProperties(cachedConfig, config); 119 } else { 120 // put any configs with an id into a map 121 map[config.id] = config; 122 } 123 } else { 124 allConfigs.push(config); 125 } 126 } 127 } 128 } 129 }, 130 131 /** 132 * An element implementing `Polymer.NeonAnimationRunnerBehavior` calls this method to configure 133 * an animation with an optional type. Elements implementing `Polymer.NeonAnimatableBehavior` 134 * should define the property `animationConfig`, which is either a configuration object 135 * or a map of animation type to array of configuration objects. 136 */ 137 getAnimationConfig: function(type) { 138 var map = {}; 139 var allConfigs = []; 140 this._getAnimationConfigRecursive(type, map, allConfigs); 141 // append the configurations saved in the map to the array 142 for (var key in map) { 143 allConfigs.push(map[key]); 144 } 145 return allConfigs; 146 } 147 148 }; 149 150</script> 151