packages feed

reload-0.0.0.1: web/bower_components/app-layout/app-box/app-box.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-flex-layout/iron-flex-layout.html">
<link rel="import" href="../../iron-resizable-behavior/iron-resizable-behavior.html">
<link rel="import" href="../app-scroll-effects/app-scroll-effects-behavior.html">

<!--
app-box is a container element that can have scroll effects - visual effects based on
scroll position. For example, the parallax effect can be used to move an image at a slower
rate than the foreground.

```html
<app-box style="height: 100px;" effects="parallax-background">
  <img background src="picture.png" style="width: 100%; height: 600px;">
</app-box>
```

Notice the `background` attribute in the `img` element; this attribute specifies that that image is used as the background.
By adding the background to the light dom, you can compose backgrounds that can change dynamically.
Alternatively, the mixin `--app-box-background-front-layer` allows to style the background. For example:

```css
  .parallaxAppBox {
    --app-box-background-front-layer: {
      background-image: url(picture.png);
    };
  }
```

Finally, app-box can have content inside. For example:

```html
<app-box effects="parallax-background">
  <h2>Sub title</h2>
</app-box>
```

## Scroll effects

Effect name | Description
----------------|-------------
`parallax-background` | A parallax effect

## Styling

Mixin | Description | Default
----------------|-------------|----------
`--app-box-background-front-layer` | Applies to the front layer of the background | {}

@group App Elements
@element app-box
@demo app-box/demo/document-scroll.html Document Scroll
@demo app-box/demo/scrolling-region.html Scrolling Region
-->

<dom-module id="app-box">
  <template>
    <style>
      :host {
        position: relative;

        display: block;
      }

      #background {
        @apply(--layout-fit);

        overflow: hidden;

        height: 100%;
      }

      #backgroundFrontLayer {
        min-height: 100%;

        pointer-events: none;

        background-size: cover;

        @apply(--app-box-background-front-layer);
      }

      #contentContainer {
        position: relative;

        width: 100%;
        height: 100%;
      }

      :host([disabled]),
      :host([disabled]) #backgroundFrontLayer {
        transition: none !important;
      }
    </style>

    <div id="background">
      <div id="backgroundFrontLayer">
        <content select="[background]"></content>
      </div>
    </div>
    <div id="contentContainer">
      <content id="content"></content>
    </div>
  </template>

  <script>
    Polymer({
      is: 'app-box',

      behaviors: [
        Polymer.AppScrollEffectsBehavior,
        Polymer.IronResizableBehavior
      ],

      listeners: {
        'iron-resize': '_resizeHandler'
      },

      /**
       * The current scroll progress.
       *
       * @type {number}
       */
      _progress: 0,

      attached: function() {
        this.resetLayout();
      },

      /**
       * Resets the layout. This method is automatically called when the element is attached to the DOM.
       *
       * @method resetLayout
       */
      resetLayout: function() {
        this.debounce('_resetLayout', function() {
          // noop if the box isn't in the rendered tree
          if (this.offsetWidth === 0 && this.offsetHeight === 0) {
            return;
          }

          var scrollTop = this._clampedScrollTop;
          var savedDisabled = this.disabled;

          this.disabled = true;
          this._elementTop = this._getElementTop();
          this._elementHeight = this.offsetHeight;
          this._cachedScrollTargetHeight = this._scrollTargetHeight;
          this._setUpEffect();
          this._updateScrollState(scrollTop);
          this.disabled = savedDisabled;
        }, 1);
      },

      _getElementTop: function() {
        var currentNode = this;
        var top = 0;

        while (currentNode && currentNode !== this.scrollTarget) {
          top += currentNode.offsetTop;
          currentNode = currentNode.offsetParent;
        }
        return top;
      },

      _updateScrollState: function(scrollTop) {
        if (this.isOnScreen()) {
          var viewportTop = this._elementTop - scrollTop;
          this._progress = 1 - (viewportTop + this._elementHeight) / this._cachedScrollTargetHeight;
          this._runEffects(this._progress, scrollTop);
        }
      },

      /**
       * Returns true if this app-box is on the screen.
       * That is, visible in the current viewport.
       *
       * @method isOnScreen
       * @return {boolean}
       */
      isOnScreen: function() {
        return this._elementTop < this._scrollTop + this._cachedScrollTargetHeight
            && this._elementTop + this._elementHeight > this._scrollTop;
      },

      _resizeHandler: function() {
        this.resetLayout();
      },

      _getDOMRef: function(id) {
        if (id === 'background') {
          return this.$.background;
        }
        if (id === 'backgroundFrontLayer') {
          return this.$.backgroundFrontLayer;
        }
      },

      /**
       * Returns an object containing the progress value of the scroll effects.
       *
       * @method getScrollState
       * @return {Object}
       */
      getScrollState: function() {
        return { progress: this._progress };
      }
    });
  </script>
</dom-module>