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<link rel="import" href="../polymer/polymer.html"> 11<link rel="import" href="../iron-meta/iron-meta.html"> 12<link rel="import" href="neon-animatable-behavior.html"> 13 14<script> 15 16 /** 17 * `Polymer.NeonAnimationRunnerBehavior` adds a method to run animations. 18 * 19 * @polymerBehavior Polymer.NeonAnimationRunnerBehavior 20 */ 21 Polymer.NeonAnimationRunnerBehaviorImpl = { 22 23 _configureAnimations: function(configs) { 24 var results = []; 25 if (configs.length > 0) { 26 for (var config, index = 0; config = configs[index]; index++) { 27 var neonAnimation = document.createElement(config.name); 28 // is this element actually a neon animation? 29 if (neonAnimation.isNeonAnimation) { 30 var result = null; 31 // configuration or play could fail if polyfills aren't loaded 32 try { 33 result = neonAnimation.configure(config); 34 // Check if we have an Effect rather than an Animation 35 if (typeof result.cancel != 'function') { 36 result = document.timeline.play(result); 37 } 38 } catch (e) { 39 result = null; 40 console.warn('Couldnt play', '(', config.name, ').', e); 41 } 42 if (result) { 43 results.push({ 44 neonAnimation: neonAnimation, 45 config: config, 46 animation: result, 47 }); 48 } 49 } else { 50 console.warn(this.is + ':', config.name, 'not found!'); 51 } 52 } 53 } 54 return results; 55 }, 56 57 _shouldComplete: function(activeEntries) { 58 var finished = true; 59 for (var i = 0; i < activeEntries.length; i++) { 60 if (activeEntries[i].animation.playState != 'finished') { 61 finished = false; 62 break; 63 } 64 } 65 return finished; 66 }, 67 68 _complete: function(activeEntries) { 69 for (var i = 0; i < activeEntries.length; i++) { 70 activeEntries[i].neonAnimation.complete(activeEntries[i].config); 71 } 72 for (var i = 0; i < activeEntries.length; i++) { 73 activeEntries[i].animation.cancel(); 74 } 75 }, 76 77 /** 78 * Plays an animation with an optional `type`. 79 * @param {string=} type 80 * @param {!Object=} cookie 81 */ 82 playAnimation: function(type, cookie) { 83 var configs = this.getAnimationConfig(type); 84 if (!configs) { 85 return; 86 } 87 this._active = this._active || {}; 88 if (this._active[type]) { 89 this._complete(this._active[type]); 90 delete this._active[type]; 91 } 92 93 var activeEntries = this._configureAnimations(configs); 94 95 if (activeEntries.length == 0) { 96 this.fire('neon-animation-finish', cookie, {bubbles: false}); 97 return; 98 } 99 100 this._active[type] = activeEntries; 101 102 for (var i = 0; i < activeEntries.length; i++) { 103 activeEntries[i].animation.onfinish = function() { 104 if (this._shouldComplete(activeEntries)) { 105 this._complete(activeEntries); 106 delete this._active[type]; 107 this.fire('neon-animation-finish', cookie, {bubbles: false}); 108 } 109 }.bind(this); 110 } 111 }, 112 113 /** 114 * Cancels the currently running animations. 115 */ 116 cancelAnimation: function() { 117 for (var k in this._animations) { 118 this._animations[k].cancel(); 119 } 120 this._animations = {}; 121 } 122 }; 123 124 /** @polymerBehavior Polymer.NeonAnimationRunnerBehavior */ 125 Polymer.NeonAnimationRunnerBehavior = [ 126 Polymer.NeonAnimatableBehavior, 127 Polymer.NeonAnimationRunnerBehaviorImpl 128 ]; 129</script> 130