OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview Card slider implementation. Allows you to create interactions | 6 * @fileoverview Card slider implementation. Allows you to create interactions |
7 * that have items that can slide left to right to reveal additional items. | 7 * that have items that can slide left to right to reveal additional items. |
8 * Works by adding the necessary event handlers to a specific DOM structure | 8 * Works by adding the necessary event handlers to a specific DOM structure |
9 * including a frame, container and cards. | 9 * including a frame, container and cards. |
10 * - The frame defines the boundary of one item. Each card will be expanded to | 10 * - The frame defines the boundary of one item. Each card will be expanded to |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 assert(view.getComputedStyle(this.container_).display == '-webkit-box', | 121 assert(view.getComputedStyle(this.container_).display == '-webkit-box', |
122 'Container should be display -webkit-box.'); | 122 'Container should be display -webkit-box.'); |
123 assert(view.getComputedStyle(this.frame_).overflow == 'hidden', | 123 assert(view.getComputedStyle(this.frame_).overflow == 'hidden', |
124 'Frame should be overflow hidden.'); | 124 'Frame should be overflow hidden.'); |
125 assert(view.getComputedStyle(this.container_).position == 'static', | 125 assert(view.getComputedStyle(this.container_).position == 'static', |
126 'Container should be position static.'); | 126 'Container should be position static.'); |
127 | 127 |
128 this.updateCardWidths_(); | 128 this.updateCardWidths_(); |
129 | 129 |
130 this.mouseWheelScrollAmount_ = 0; | 130 this.mouseWheelScrollAmount_ = 0; |
| 131 this.mouseWheelCardSelected_ = false; |
| 132 this.mouseWheelIsContinuous_ = false; |
131 this.scrollClearTimeout_ = null; | 133 this.scrollClearTimeout_ = null; |
132 this.frame_.addEventListener('mousewheel', | 134 this.frame_.addEventListener('mousewheel', |
133 this.onMouseWheel_.bind(this)); | 135 this.onMouseWheel_.bind(this)); |
134 | 136 |
135 if (document.documentElement.getAttribute('touchui')) { | 137 if (document.documentElement.getAttribute('touchui')) { |
136 this.container_.addEventListener(TouchHandler.EventType.TOUCH_START, | 138 this.container_.addEventListener(TouchHandler.EventType.TOUCH_START, |
137 this.onTouchStart_.bind(this)); | 139 this.onTouchStart_.bind(this)); |
138 this.container_.addEventListener(TouchHandler.EventType.DRAG_START, | 140 this.container_.addEventListener(TouchHandler.EventType.DRAG_START, |
139 this.onDragStart_.bind(this)); | 141 this.onDragStart_.bind(this)); |
140 this.container_.addEventListener(TouchHandler.EventType.DRAG_MOVE, | 142 this.container_.addEventListener(TouchHandler.EventType.DRAG_MOVE, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 * Handle horizontal scrolls to flip between pages. | 228 * Handle horizontal scrolls to flip between pages. |
227 * @private | 229 * @private |
228 */ | 230 */ |
229 onMouseWheel_: function(e) { | 231 onMouseWheel_: function(e) { |
230 if (e.wheelDeltaX == 0) | 232 if (e.wheelDeltaX == 0) |
231 return; | 233 return; |
232 | 234 |
233 // Prevent OS X 10.7+ history swiping on the NTP. | 235 // Prevent OS X 10.7+ history swiping on the NTP. |
234 e.preventDefault(); | 236 e.preventDefault(); |
235 | 237 |
236 // Mac value feels ok with multitouch trackpads and magic mice | 238 // Continuous devices such as an Apple Touchpad or Apple MagicMouse will |
237 // (with physical scrollwheel, too), but not so great with logitech | 239 // send arbitrary delta values. Conversly, standard mousewheels will |
238 // mice. | 240 // send delta values in increments of 120. (There is of course a small |
239 var scrollAmountPerPage = cr.isMac ? 400 : 120; | 241 // chance we mistake a continuous device for a non-continuous device. |
240 if (!ntp4.isRTL()) | 242 // Unfortunately there isn't a better way to do this until real touch |
241 scrollAmountPerPage *= -1; | 243 // events are available to desktop clients.) |
242 this.mouseWheelScrollAmount_ += e.wheelDeltaX; | 244 var DISCRETE_DELTA = 120; |
243 if (Math.abs(this.mouseWheelScrollAmount_) >= | 245 if (e.wheelDeltaX % DISCRETE_DELTA) |
244 Math.abs(scrollAmountPerPage)) { | 246 this.mouseWheelIsContinuous_ = true; |
245 var pagesToScroll = this.mouseWheelScrollAmount_ / scrollAmountPerPage; | 247 |
246 pagesToScroll = | 248 if (this.mouseWheelIsContinuous_) { |
247 (pagesToScroll > 0 ? Math.floor : Math.ceil)(pagesToScroll); | 249 // For continuous devices, detect a page swipe when the accumulated |
| 250 // delta matches a pre-defined threshhold. After changing the page, |
| 251 // ignore wheel events for a short time before repeating this process. |
| 252 if (this.mouseWheelCardSelected_) return; |
| 253 this.mouseWheelScrollAmount_ += e.wheelDeltaX; |
| 254 if (Math.abs(this.mouseWheelScrollAmount_) >= 600) { |
| 255 var pagesToScroll = this.mouseWheelScrollAmount_ > 0 ? 1 : -1; |
| 256 if (!ntp4.isRTL()) |
| 257 pagesToScroll *= -1; |
| 258 var newCardIndex = this.currentCard + pagesToScroll; |
| 259 newCardIndex = Math.min(this.cards_.length - 1, |
| 260 Math.max(0, newCardIndex)); |
| 261 this.selectCard(newCardIndex, true); |
| 262 this.mouseWheelCardSelected_ = true; |
| 263 } |
| 264 } else { |
| 265 // For discrete devices, consider each wheel tick a page change. |
| 266 var pagesToScroll = e.wheelDeltaX / DISCRETE_DELTA; |
| 267 if (!ntp4.isRTL()) |
| 268 pagesToScroll *= -1; |
248 var newCardIndex = this.currentCard + pagesToScroll; | 269 var newCardIndex = this.currentCard + pagesToScroll; |
249 newCardIndex = Math.min(this.cards_.length - 1, | 270 newCardIndex = Math.min(this.cards_.length - 1, |
250 Math.max(0, newCardIndex)); | 271 Math.max(0, newCardIndex)); |
251 this.selectCard(newCardIndex, true); | 272 this.selectCard(newCardIndex, true); |
252 this.mouseWheelScrollAmount_ -= pagesToScroll * scrollAmountPerPage; | |
253 } | 273 } |
254 | 274 |
255 // We got a mouse wheel event, so cancel any pending scroll wheel timeout. | 275 // We got a mouse wheel event, so cancel any pending scroll wheel timeout. |
256 if (this.scrollClearTimeout_ != null) | 276 if (this.scrollClearTimeout_ != null) |
257 clearTimeout(this.scrollClearTimeout_); | 277 clearTimeout(this.scrollClearTimeout_); |
258 // If we didn't use up all the scroll, hold onto it for a little bit, but | 278 // If we didn't use up all the scroll, hold onto it for a little bit, but |
259 // drop it after a delay. | 279 // drop it after a delay. |
260 if (this.mouseWheelScrollAmount_ != 0) { | 280 if (this.mouseWheelScrollAmount_ != 0) { |
261 this.scrollClearTimeout_ = | 281 this.scrollClearTimeout_ = |
262 setTimeout(this.clearMouseWheelScroll_.bind(this), 500); | 282 setTimeout(this.clearMouseWheelScroll_.bind(this), 500); |
263 } | 283 } |
264 }, | 284 }, |
265 | 285 |
266 /** | 286 /** |
267 * Resets the amount of horizontal scroll we've seen to 0. See | 287 * Resets the amount of horizontal scroll we've seen to 0. See |
268 * onMouseWheel_. | 288 * onMouseWheel_. |
269 * @private | 289 * @private |
270 */ | 290 */ |
271 clearMouseWheelScroll_: function() { | 291 clearMouseWheelScroll_: function() { |
272 this.mouseWheelScrollAmount_ = 0; | 292 this.mouseWheelScrollAmount_ = 0; |
| 293 this.mouseWheelCardSelected_ = false; |
273 }, | 294 }, |
274 | 295 |
275 /** | 296 /** |
276 * Selects a new card, ensuring that it is a valid index, transforming the | 297 * Selects a new card, ensuring that it is a valid index, transforming the |
277 * view and possibly calling the change card callback. | 298 * view and possibly calling the change card callback. |
278 * @param {number} newCardIndex Index of card to show. | 299 * @param {number} newCardIndex Index of card to show. |
279 * @param {boolean=} opt_animate If true will animate transition from | 300 * @param {boolean=} opt_animate If true will animate transition from |
280 * current position to new position. | 301 * current position to new position. |
281 */ | 302 */ |
282 selectCard: function(newCardIndex, opt_animate) { | 303 selectCard: function(newCardIndex, opt_animate) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 // Stop listening to any current touch | 450 // Stop listening to any current touch |
430 this.touchHandler_.cancelTouch(); | 451 this.touchHandler_.cancelTouch(); |
431 | 452 |
432 // Ensure we're at a card bounary | 453 // Ensure we're at a card bounary |
433 this.transformToCurrentCard_(true); | 454 this.transformToCurrentCard_(true); |
434 }, | 455 }, |
435 }; | 456 }; |
436 | 457 |
437 return CardSlider; | 458 return CardSlider; |
438 })(); | 459 })(); |
OLD | NEW |