diff options
Diffstat (limited to 'catapult/third_party/polymer/components/neon-animation/neon-animated-pages.html')
-rw-r--r-- | catapult/third_party/polymer/components/neon-animation/neon-animated-pages.html | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/catapult/third_party/polymer/components/neon-animation/neon-animated-pages.html b/catapult/third_party/polymer/components/neon-animation/neon-animated-pages.html new file mode 100644 index 00000000..983cb471 --- /dev/null +++ b/catapult/third_party/polymer/components/neon-animation/neon-animated-pages.html @@ -0,0 +1,220 @@ +<!-- +@license +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> +<link rel="import" href="../polymer/polymer.html"> +<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html"> +<link rel="import" href="../iron-selector/iron-selectable.html"> +<link rel="import" href="neon-animation-runner-behavior.html"> + +<!-- +Material design: [Meaningful transitions](https://www.google.com/design/spec/animation/meaningful-transitions.html) + +`neon-animated-pages` manages a set of pages and runs an animation when switching between them. Its +children pages should implement `Polymer.NeonAnimatableBehavior` and define `entry` and `exit` +animations to be run when switching to or switching out of the page. + +@group Neon Elements +@element neon-animated-pages +@demo demo/index.html +--> + +<dom-module id="neon-animated-pages"> + <template> + <style> + :host { + display: block; + position: relative; + } + + :host > ::content > * { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + } + + :host > ::content > :not(.iron-selected):not(.neon-animating) { + display: none !important; + } + + :host > ::content > .neon-animating { + pointer-events: none; + } + </style> + + <content id="content"></content> + </template> + +</dom-module> + +<script> +(function() { + + Polymer({ + + is: 'neon-animated-pages', + + behaviors: [ + Polymer.IronResizableBehavior, + Polymer.IronSelectableBehavior, + Polymer.NeonAnimationRunnerBehavior + ], + + properties: { + + activateEvent: { + type: String, + value: '' + }, + + // if true, the initial page selection will also be animated according to its animation config. + animateInitialSelection: { + type: Boolean, + value: false + } + + }, + + listeners: { + 'iron-select': '_onIronSelect', + 'neon-animation-finish': '_onNeonAnimationFinish' + }, + + _onIronSelect: function(event) { + var selectedPage = event.detail.item; + + // Only consider child elements. + if (this.items.indexOf(selectedPage) < 0) { + return; + } + + var oldPage = this._valueToItem(this._prevSelected) || false; + this._prevSelected = this.selected; + + // on initial load and if animateInitialSelection is negated, simply display selectedPage. + if (!oldPage && !this.animateInitialSelection) { + this._completeSelectedChanged(); + return; + } + + this.animationConfig = []; + + // configure selectedPage animations. + if (this.entryAnimation) { + this.animationConfig.push({ + name: this.entryAnimation, + node: selectedPage + }); + } else { + if (selectedPage.getAnimationConfig) { + this.animationConfig.push({ + animatable: selectedPage, + type: 'entry' + }); + } + } + + // configure oldPage animations iff exists. + if (oldPage) { + + // cancel the currently running animation if one is ongoing. + if (oldPage.classList.contains('neon-animating')) { + this._squelchNextFinishEvent = true; + this.cancelAnimation(); + this._completeSelectedChanged(); + this._squelchNextFinishEvent = false; + } + + // configure the animation. + if (this.exitAnimation) { + this.animationConfig.push({ + name: this.exitAnimation, + node: oldPage + }); + } else { + if (oldPage.getAnimationConfig) { + this.animationConfig.push({ + animatable: oldPage, + type: 'exit' + }); + } + } + + // display the oldPage during the transition. + oldPage.classList.add('neon-animating'); + } + + // display the selectedPage during the transition. + selectedPage.classList.add('neon-animating'); + + // actually run the animations. + if (this.animationConfig.length >= 1) { + + // on first load, ensure we run animations only after element is attached. + if (!this.isAttached) { + this.async(function () { + this.playAnimation(undefined, { + fromPage: null, + toPage: selectedPage + }); + }); + + } else { + this.playAnimation(undefined, { + fromPage: oldPage, + toPage: selectedPage + }); + } + + } else { + this._completeSelectedChanged(oldPage, selectedPage); + } + }, + + /** + * @param {Object=} oldPage + * @param {Object=} selectedPage + */ + _completeSelectedChanged: function(oldPage, selectedPage) { + if (selectedPage) { + selectedPage.classList.remove('neon-animating'); + } + if (oldPage) { + oldPage.classList.remove('neon-animating'); + } + if (!selectedPage || !oldPage) { + var nodes = Polymer.dom(this.$.content).getDistributedNodes(); + for (var node, index = 0; node = nodes[index]; index++) { + node.classList && node.classList.remove('neon-animating'); + } + } + this.async(this._notifyPageResize); + }, + + _onNeonAnimationFinish: function(event) { + if (this._squelchNextFinishEvent) { + this._squelchNextFinishEvent = false; + return; + } + this._completeSelectedChanged(event.detail.fromPage, event.detail.toPage); + }, + + _notifyPageResize: function() { + var selectedPage = this.selectedItem || this._valueToItem(this.selected); + this.resizerShouldNotify = function(element) { + return element == selectedPage; + } + this.notifyResize(); + } + + }) + +})(); +</script> |