• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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