aboutsummaryrefslogtreecommitdiff
path: root/catapult/third_party/polymer/components/neon-animation/neon-animated-pages.html
diff options
context:
space:
mode:
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.html220
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>