221 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			HTML
		
	
	
	
<!--
 | 
						|
@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>
 |