• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1
2
3  Polymer('core-animated-pages',{
4
5    eventDelegates: {
6      'core-transitionend': 'transitionEnd'
7    },
8
9    /**
10     * A space-delimited string of transitions to use when switching between pages in this element.
11     * The strings are `id`s of `core-transition-pages` elements included elsewhere. See the
12     * individual transition's document for specific details.
13     *
14     * @attribute transitions
15     * @type string
16     * @default ''
17     */
18    transitions: '',
19
20    selected: 0,
21
22    /**
23     * The last page selected. This property is useful to dynamically set transitions based
24     * on incoming and outgoing pages.
25     *
26     * @attribute lastSelected
27     * @type Object
28     * @default null
29     */
30    lastSelected: null,
31
32    registerCallback: function() {
33      this.tmeta = document.createElement('core-transition');
34    },
35
36    created: function() {
37      this._transitions = [];
38      this.transitioning = [];
39    },
40
41    transitionsChanged: function() {
42      this._transitions = this.transitions.split(' ');
43    },
44
45    _transitionsChanged: function(old) {
46      if (this._transitionElements) {
47        this._transitionElements.forEach(function(t) {
48          t.teardown(this);
49        }, this);
50      }
51      this._transitionElements = [];
52      this._transitions.forEach(function(transitionId) {
53        var t = this.getTransition(transitionId);
54        if (t) {
55          this._transitionElements.push(t);
56          t.setup(this);
57        }
58      }, this);
59    },
60
61    getTransition: function(transitionId) {
62      return this.tmeta.byId(transitionId);
63    },
64
65    selectionSelect: function(e, detail) {
66      this.updateSelectedItem();
67      // Wait to call applySelection when we run the transition
68    },
69
70    applyTransition: function(src, dst) {
71      if (this.animating) {
72        this.cancelAsync(this.animating);
73        this.animating = null;
74      }
75
76      Platform.flush();
77
78      if (this.transitioning.indexOf(src) === -1) {
79        this.transitioning.push(src);
80      }
81      if (this.transitioning.indexOf(dst) === -1) {
82        this.transitioning.push(dst);
83      }
84      // force src, dst to display
85      src.setAttribute('animate', '');
86      dst.setAttribute('animate', '');
87      //
88      var options = {
89        src: src,
90        dst: dst,
91        easing: 'cubic-bezier(0.4, 0, 0.2, 1)'
92      }
93
94      // fire an event so clients have a chance to do something when the
95      // new page becomes visible but before it draws.
96      this.fire('core-animated-pages-transition-prepare');
97
98      //
99      // prepare transition
100      this._transitionElements.forEach(function(transition) {
101        transition.prepare(this, options);
102      }, this);
103      //
104      // force layout!
105      src.offsetTop;
106
107      //
108      // apply selection
109      this.applySelection(dst, true);
110      this.applySelection(src, false);
111      //
112      // start transition
113      this._transitionElements.forEach(function(transition) {
114        transition.go(this, options);
115      }, this);
116
117      if (!this._transitionElements.length) {
118        this.complete();
119      } else {
120        this.animating = this.async(this.complete.bind(this), null, 5000);
121      }
122    },
123
124    complete: function() {
125      if (this.animating) {
126        this.cancelAsync(this.animating);
127        this.animating = null;
128      }
129
130      this.transitioning.forEach(function(t) {
131        t.removeAttribute('animate');
132      });
133      this.transitioning = [];
134
135      this._transitionElements.forEach(function(transition) {
136        transition.ensureComplete(this);
137      }, this);
138
139      this.fire('core-animated-pages-transition-end');
140    },
141
142    transitionEnd: function(e) {
143      if (this.transitioning.length) {
144        var completed = true;
145        this._transitionElements.forEach(function(transition) {
146          if (!transition.completed) {
147            completed = false;
148          }
149        });
150        if (completed) {
151          this.job('transitionWatch', function() {
152            this.complete();
153          }, 100);
154        }
155      }
156    },
157
158    selectedChanged: function(old) {
159      this.lastSelected = old;
160      this.super(arguments);
161    },
162
163    selectedItemChanged: function(oldItem) {
164      this.super(arguments);
165
166      if (!oldItem) {
167        this.applySelection(this.selectedItem, true);
168        return;
169      }
170
171      if (this.hasAttribute('no-transition') || !this._transitionElements || !this._transitionElements.length) {
172        this.applySelection(oldItem, false);
173        this.applySelection(this.selectedItem, true);
174        return;
175      }
176
177      if (oldItem && this.selectedItem) {
178        // TODO(sorvell): allow bindings to update first?
179        var self = this;
180        Platform.flush();
181        Platform.endOfMicrotask(function() {
182          self.applyTransition(oldItem, self.selectedItem);
183        });
184      }
185    }
186
187  });
188
189