Home | History | Annotate | Download | only in paper-dropdown
      1 <!--
      2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
      3 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
      4 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
      5 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
      6 Code distributed by Google as part of the polymer project is also
      7 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
      8 -->
      9 <!--
     10 
     11 `paper-dropdown-transition` is a transition for `paper-dropdown`.
     12 
     13 Add the class `menu` to a `core-selector` child of the `paper-dropdown` to
     14 enable the optional list cascade transition.
     15 
     16 @group Paper Elements
     17 @class paper-dropdown-transition
     18 @extends core-transition-css
     19 @status unstable
     20 -->
     21 <link href="../polymer/polymer.html" rel="import">
     22 <link href="../core-transition/core-transition-css.html" rel="import">
     23 <link href="../core-animation/web-animations.html" rel="import">
     24 
     25 <polymer-element name="paper-dropdown-transition" extends="core-transition-css">
     26   <template>
     27     <link href="paper-dropdown-transition.css" rel="stylesheet" no-shim>
     28   </template>
     29   <script>
     30     Polymer('paper-dropdown-transition', {
     31 
     32       publish: {
     33 
     34         /**
     35          * The duration of the transition in ms. You can also set the duration by
     36          * setting a `duration` attribute on the target:
     37          *
     38          *    <paper-dropdown duration="1000"></paper-dropdown>
     39          *
     40          * @attribute duration
     41          * @type number
     42          * @default 500
     43          */
     44         duration: 500
     45 
     46       },
     47 
     48       setup: function(node) {
     49         this.super(arguments);
     50 
     51         var to = {
     52           'top': '0%',
     53           'left': '0%',
     54           'bottom': '100%',
     55           'right': '100%'
     56         };
     57 
     58         var bg = node.$.background;
     59         bg.style.webkitTransformOrigin = to[node.halign] + ' ' + to[node.valign];
     60         bg.style.transformOrigin = to[node.halign] + ' ' + to[node.valign];
     61       },
     62 
     63       transitionOpened: function(node, opened) {
     64         this.super(arguments);
     65 
     66         if (opened) {
     67           if (this.player) {
     68             this.player.cancel();
     69           }
     70 
     71           var duration = Number(node.getAttribute('duration')) || this.duration;
     72 
     73           var anims = [];
     74 
     75           var size = node.getBoundingClientRect();
     76 
     77           var ink = node.$.ripple;
     78           // var offset = 40 / Math.max(size.width, size.height);
     79           var offset = 0.2;
     80           anims.push(new Animation(ink, [{
     81             'opacity': 0.9,
     82             'transform': 'scale(0)',
     83           }, {
     84             'opacity': 0.9,
     85             'transform': 'scale(1)'
     86           }], {
     87             duration: duration * offset
     88           }));
     89 
     90           var bg = node.$.background;
     91           var sx = 40 / size.width;
     92           var sy = 40 / size.height;
     93           anims.push(new Animation(bg, [{
     94             'opacity': 0.9,
     95             'transform': 'scale(' + sx + ',' + sy + ')',
     96           }, {
     97             'opacity': 1,
     98             'transform': 'scale(' + Math.max(sx, 0.95) + ',' + Math.max(sy, 0.5) + ')'
     99           }, {
    100             'opacity': 1,
    101             'transform': 'scale(1, 1)'
    102           }], {
    103             delay: duration * offset,
    104             duration: duration * (1 - offset),
    105             fill: 'forwards'
    106           }));
    107 
    108           var menu = node.querySelector('.menu');
    109           if (menu) {
    110             var items = menu.items || menu.children.array();
    111             var itemDelay = offset + (1 - offset) / 2;
    112             var itemDuration = duration * (1 - itemDelay) / items.length;
    113             var reverse = this.valign === 'bottom';
    114 
    115             items.forEach(function(item, i) {
    116               anims.push(new Animation(item, [{
    117                 'opacity': 0
    118               }, {
    119                 'opacity': 1
    120               }], {
    121                 delay: duration * itemDelay + itemDuration * (reverse ? items.length - 1 - i : i),
    122                 duration: itemDuration,
    123                 fill: 'both'
    124               }));
    125             }.bind(this));
    126 
    127             anims.push(new Animation(node.$.scroller, [{
    128               'opacity': 1
    129             }, {
    130               'opacity': 1
    131             }], {
    132               delay: duration * itemDelay,
    133               duration: itemDuration * items.length,
    134               fill: 'both'
    135             }));
    136 
    137           } else {
    138             anims.push(new Animation(node.$.scroller, [{
    139               'opacity': 0
    140             }, {
    141               'opacity': 1
    142             }], {
    143               delay: duration * (offset + (1 - offset) / 2),
    144               duration: duration * 0.5,
    145               fill: 'both'
    146             }));
    147           }
    148 
    149           var group = new AnimationGroup(anims, {
    150             easing: 'cubic-bezier(0.4, 0, 0.2, 1)'
    151           });
    152           this.player = document.timeline.play(group);
    153           this.player.onfinish = function() {
    154             this.fire('core-transitionend', this, node);
    155           }.bind(this);
    156 
    157         } else {
    158           this.fire('core-transitionend', this, node);
    159         }
    160       },
    161 
    162     });
    163   </script>
    164 </polymer-element>
    165 
    166 <paper-dropdown-transition id="paper-dropdown-transition"></paper-dropdown-transition>