OLD | NEW |
| (Empty) |
1 | |
2 (function() { | |
3 | |
4 'use strict'; | |
5 | |
6 Polymer({ | |
7 | |
8 /** | |
9 * Fired when the content has been scrolled. | |
10 * | |
11 * @event content-scroll | |
12 */ | |
13 | |
14 /** | |
15 * Fired when the header is transformed. | |
16 * | |
17 * @event paper-header-transform | |
18 */ | |
19 | |
20 is: 'paper-scroll-header-panel', | |
21 | |
22 behaviors: [ | |
23 Polymer.IronResizableBehavior | |
24 ], | |
25 | |
26 properties: { | |
27 | |
28 /** | |
29 * If true, the header's height will condense to `_condensedHeaderHeight` | |
30 * as the user scrolls down from the top of the content area. | |
31 */ | |
32 condenses: { | |
33 type: Boolean, | |
34 value: false, | |
35 observer: '_condensesChanged' | |
36 }, | |
37 | |
38 /** | |
39 * If true, no cross-fade transition from one background to another. | |
40 */ | |
41 noDissolve: { | |
42 type: Boolean, | |
43 value: false | |
44 }, | |
45 | |
46 /** | |
47 * If true, the header doesn't slide back in when scrolling back up. | |
48 */ | |
49 noReveal: { | |
50 type: Boolean, | |
51 value: false | |
52 }, | |
53 | |
54 /** | |
55 * If true, the header is fixed to the top and never moves away. | |
56 */ | |
57 fixed: { | |
58 type: Boolean, | |
59 value: false | |
60 }, | |
61 | |
62 /** | |
63 * If true, the condensed header is always shown and does not move away. | |
64 */ | |
65 keepCondensedHeader: { | |
66 type: Boolean, | |
67 value: false | |
68 }, | |
69 | |
70 /** | |
71 * The height of the header when it is at its full size. | |
72 * | |
73 * By default, the height will be measured when it is ready. If the heigh
t | |
74 * changes later the user needs to either set this value to reflect the | |
75 * new height or invoke `measureHeaderHeight()`. | |
76 */ | |
77 headerHeight: { | |
78 type: Number, | |
79 value: 0 | |
80 }, | |
81 | |
82 /** | |
83 * The height of the header when it is condensed. | |
84 * | |
85 * By default, `_condensedHeaderHeight` is 1/3 of `headerHeight` unless | |
86 * this is specified. | |
87 */ | |
88 condensedHeaderHeight: { | |
89 type: Number, | |
90 value: 0 | |
91 }, | |
92 | |
93 /** | |
94 * By default, the top part of the header stays when the header is being | |
95 * condensed. Set this to true if you want the top part of the header | |
96 * to be scrolled away. | |
97 */ | |
98 scrollAwayTopbar: { | |
99 type: Boolean, | |
100 value: false | |
101 }, | |
102 | |
103 _headerMargin: { | |
104 type: Number | |
105 }, | |
106 | |
107 _prevScrollTop: { | |
108 type: Number | |
109 }, | |
110 | |
111 _y: { | |
112 type: Number | |
113 } | |
114 | |
115 }, | |
116 | |
117 observers: [ | |
118 '_setup(_headerMargin, headerHeight, fixed)', | |
119 '_headerHeightChanged(headerHeight, condensedHeaderHeight)', | |
120 '_condensedHeaderHeightChanged(headerHeight, condensedHeaderHeight)' | |
121 ], | |
122 | |
123 listeners: { | |
124 'iron-resize': 'measureHeaderHeight' | |
125 }, | |
126 | |
127 ready: function() { | |
128 this.async(this.measureHeaderHeight, 5); | |
129 this._scrollHandler = this._scroll.bind(this); | |
130 this.scroller.addEventListener('scroll', this._scrollHandler); | |
131 }, | |
132 | |
133 detached: function() { | |
134 this.scroller.removeEventListener('scroll', this._scrollHandler); | |
135 }, | |
136 | |
137 /** | |
138 * Returns the header element. | |
139 * | |
140 * @property header | |
141 * @type Object | |
142 */ | |
143 get header() { | |
144 return Polymer.dom(this.$.headerContent).getDistributedNodes()[0]; | |
145 }, | |
146 | |
147 /** | |
148 * Returns the content element. | |
149 * | |
150 * @property content | |
151 * @type Object | |
152 */ | |
153 get content() { | |
154 return Polymer.dom(this.$.mainContent).getDistributedNodes()[0]; | |
155 }, | |
156 | |
157 /** | |
158 * Returns the scrollable element. | |
159 * | |
160 * @property scroller | |
161 * @type Object | |
162 */ | |
163 get scroller() { | |
164 return this.$.mainContainer; | |
165 }, | |
166 | |
167 /** | |
168 * Invoke this to tell `paper-scroll-header-panel` to re-measure the header'
s | |
169 * height. | |
170 * | |
171 * @method measureHeaderHeight | |
172 */ | |
173 measureHeaderHeight: function() { | |
174 var header = this.header; | |
175 if (header && header.offsetHeight) { | |
176 this.headerHeight = header.offsetHeight; | |
177 } | |
178 }, | |
179 | |
180 _headerHeightChanged: function() { | |
181 if (!this.condensedHeaderHeight) { | |
182 // assume condensedHeaderHeight is 1/3 of the headerHeight | |
183 this.condensedHeaderHeight = this.headerHeight * 1 / 3; | |
184 } | |
185 }, | |
186 | |
187 _condensedHeaderHeightChanged: function() { | |
188 if (this.headerHeight) { | |
189 this._headerMargin = this.headerHeight - this.condensedHeaderHeight; | |
190 } | |
191 }, | |
192 | |
193 _condensesChanged: function() { | |
194 if (this.condenses) { | |
195 this._scroll(); | |
196 } else { | |
197 // reset transform/opacity set on the header | |
198 this._condenseHeader(null); | |
199 } | |
200 }, | |
201 | |
202 _setup: function() { | |
203 var s = this.scroller.style; | |
204 s.paddingTop = this.fixed ? '' : this.headerHeight + 'px'; | |
205 | |
206 s.top = this.fixed ? this.headerHeight + 'px' : ''; | |
207 | |
208 if (this.fixed) { | |
209 this._transformHeader(null); | |
210 } else { | |
211 this._scroll(); | |
212 } | |
213 }, | |
214 | |
215 _transformHeader: function(y) { | |
216 var s = this.$.headerContainer.style; | |
217 this._translateY(s, -y); | |
218 | |
219 if (this.condenses) { | |
220 this._condenseHeader(y); | |
221 } | |
222 | |
223 this.fire('paper-header-transform', {y: y, height: this.headerHeight, | |
224 condensedHeight: this.condensedHeaderHeight}); | |
225 }, | |
226 | |
227 _condenseHeader: function(y) { | |
228 var reset = (y === null); | |
229 | |
230 // adjust top bar in core-header so the top bar stays at the top | |
231 if (!this.scrollAwayTopbar && this.header.$ && this.header.$.topBar) { | |
232 this._translateY(this.header.$.topBar.style, | |
233 reset ? null : Math.min(y, this._headerMargin)); | |
234 } | |
235 // transition header bg | |
236 var hbg = this.$.headerBg.style; | |
237 if (!this.noDissolve) { | |
238 hbg.opacity = reset ? '' : (this._headerMargin - y) / this._headerMargin
; | |
239 } | |
240 // adjust header bg so it stays at the center | |
241 this._translateY(hbg, reset ? null : y / 2); | |
242 // transition condensed header bg | |
243 if (!this.noDissolve) { | |
244 var chbg = this.$.condensedHeaderBg.style; | |
245 chbg = this.$.condensedHeaderBg.style; | |
246 chbg.opacity = reset ? '' : y / this._headerMargin; | |
247 | |
248 // adjust condensed header bg so it stays at the center | |
249 this._translateY(chbg, reset ? null : y / 2); | |
250 } | |
251 }, | |
252 | |
253 _translateY: function(s, y) { | |
254 var t = (y === null) ? '' : 'translate3d(0, ' + y + 'px, 0)'; | |
255 setTransform(s, t); | |
256 }, | |
257 | |
258 _scroll: function(event) { | |
259 if (!this.header) { | |
260 return; | |
261 } | |
262 | |
263 var sTop = this.scroller.scrollTop; | |
264 | |
265 this._y = this._y || 0; | |
266 this._prevScrollTop = this._prevScrollTop || 0; | |
267 | |
268 var y = Math.min(this.keepCondensedHeader ? | |
269 this._headerMargin : this.headerHeight, Math.max(0, | |
270 (this.noReveal ? sTop : this._y + sTop - this._prevScrollTop))); | |
271 | |
272 if (this.condenses && this._prevScrollTop >= sTop && sTop > this._headerMa
rgin) { | |
273 y = Math.max(y, this._headerMargin); | |
274 } | |
275 | |
276 if (!event || !this.fixed && y !== this._y) { | |
277 this._transformHeader(y); | |
278 } | |
279 | |
280 this._prevScrollTop = Math.max(sTop, 0); | |
281 this._y = y; | |
282 | |
283 if (event) { | |
284 this.fire('content-scroll', {target: this.scroller}, this, false); | |
285 } | |
286 } | |
287 | |
288 }); | |
289 | |
290 //determine proper transform mechanizm | |
291 if (document.documentElement.style.transform !== undefined) { | |
292 var setTransform = function(style, string) { | |
293 style.transform = string; | |
294 } | |
295 } else { | |
296 var setTransform = function(style, string) { | |
297 style.webkitTransform = string; | |
298 } | |
299 } | |
300 | |
301 })(); | |
302 | |
OLD | NEW |