OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 deltaX_: 0, | 112 deltaX_: 0, |
113 | 113 |
114 /** | 114 /** |
115 * Initialize all elements and event handlers. Must call after construction | 115 * Initialize all elements and event handlers. Must call after construction |
116 * and before usage. | 116 * and before usage. |
117 * @param {boolean} ignoreMouseWheelEvents If true, horizontal mouse wheel | 117 * @param {boolean} ignoreMouseWheelEvents If true, horizontal mouse wheel |
118 * events will be ignored, rather than flipping between pages. | 118 * events will be ignored, rather than flipping between pages. |
119 */ | 119 */ |
120 initialize: function(ignoreMouseWheelEvents) { | 120 initialize: function(ignoreMouseWheelEvents) { |
121 var view = this.container_.ownerDocument.defaultView; | 121 var view = this.container_.ownerDocument.defaultView; |
122 assert(view.getComputedStyle(this.container_).display == '-webkit-box', | 122 assert( |
| 123 view.getComputedStyle(this.container_).display == '-webkit-box', |
123 'Container should be display -webkit-box.'); | 124 'Container should be display -webkit-box.'); |
124 assert(view.getComputedStyle(this.frame_).overflow == 'hidden', | 125 assert( |
| 126 view.getComputedStyle(this.frame_).overflow == 'hidden', |
125 'Frame should be overflow hidden.'); | 127 'Frame should be overflow hidden.'); |
126 assert(view.getComputedStyle(this.container_).position == 'static', | 128 assert( |
| 129 view.getComputedStyle(this.container_).position == 'static', |
127 'Container should be position static.'); | 130 'Container should be position static.'); |
128 | 131 |
129 this.updateCardWidths_(); | 132 this.updateCardWidths_(); |
130 | 133 |
131 this.mouseWheelScrollAmount_ = 0; | 134 this.mouseWheelScrollAmount_ = 0; |
132 this.mouseWheelCardSelected_ = false; | 135 this.mouseWheelCardSelected_ = false; |
133 this.mouseWheelIsContinuous_ = false; | 136 this.mouseWheelIsContinuous_ = false; |
134 this.scrollClearTimeout_ = null; | 137 this.scrollClearTimeout_ = null; |
135 if (!ignoreMouseWheelEvents) { | 138 if (!ignoreMouseWheelEvents) { |
136 this.frame_.addEventListener('mousewheel', | 139 this.frame_.addEventListener( |
137 this.onMouseWheel_.bind(this)); | 140 'mousewheel', this.onMouseWheel_.bind(this)); |
138 } | 141 } |
139 this.container_.addEventListener( | 142 this.container_.addEventListener( |
140 'webkitTransitionEnd', this.onWebkitTransitionEnd_.bind(this)); | 143 'webkitTransitionEnd', this.onWebkitTransitionEnd_.bind(this)); |
141 | 144 |
142 // Also support touch events in case a touch screen happens to be | 145 // Also support touch events in case a touch screen happens to be |
143 // available. Note that this has minimal impact in the common case of | 146 // available. Note that this has minimal impact in the common case of |
144 // no touch events (eg. we're mainly just adding listeners for events that | 147 // no touch events (eg. we're mainly just adding listeners for events that |
145 // will never trigger). | 148 // will never trigger). |
146 var TouchHandler = cr.ui.TouchHandler; | 149 var TouchHandler = cr.ui.TouchHandler; |
147 this.container_.addEventListener(TouchHandler.EventType.TOUCH_START, | 150 this.container_.addEventListener( |
148 this.onTouchStart_.bind(this)); | 151 TouchHandler.EventType.TOUCH_START, this.onTouchStart_.bind(this)); |
149 this.container_.addEventListener(TouchHandler.EventType.DRAG_START, | 152 this.container_.addEventListener( |
150 this.onDragStart_.bind(this)); | 153 TouchHandler.EventType.DRAG_START, this.onDragStart_.bind(this)); |
151 this.container_.addEventListener(TouchHandler.EventType.DRAG_MOVE, | 154 this.container_.addEventListener( |
152 this.onDragMove_.bind(this)); | 155 TouchHandler.EventType.DRAG_MOVE, this.onDragMove_.bind(this)); |
153 this.container_.addEventListener(TouchHandler.EventType.DRAG_END, | 156 this.container_.addEventListener( |
154 this.onDragEnd_.bind(this)); | 157 TouchHandler.EventType.DRAG_END, this.onDragEnd_.bind(this)); |
155 | 158 |
156 this.touchHandler_.enable(/* opt_capture */ false); | 159 this.touchHandler_.enable(/* opt_capture */ false); |
157 }, | 160 }, |
158 | 161 |
159 /** | 162 /** |
160 * Use in cases where the width of the frame has changed in order to update | 163 * Use in cases where the width of the frame has changed in order to update |
161 * the width of cards. For example should be used when orientation changes | 164 * the width of cards. For example should be used when orientation changes |
162 * in full width sliders. | 165 * in full width sliders. |
163 * @param {number} newCardWidth Width all cards should have, in pixels. | 166 * @param {number} newCardWidth Width all cards should have, in pixels. |
164 */ | 167 */ |
165 resize: function(newCardWidth) { | 168 resize: function(newCardWidth) { |
166 if (newCardWidth != this.cardWidth_) { | 169 if (newCardWidth != this.cardWidth_) { |
167 this.cardWidth_ = newCardWidth; | 170 this.cardWidth_ = newCardWidth; |
168 | 171 |
169 this.updateCardWidths_(); | 172 this.updateCardWidths_(); |
170 | 173 |
171 // Must upate the transform on the container to show the correct card. | 174 // Must upate the transform on the container to show the correct card. |
172 this.transformToCurrentCard_(); | 175 this.transformToCurrentCard_(); |
173 } | 176 } |
174 }, | 177 }, |
175 | 178 |
176 /** | 179 /** |
177 * Sets the cards used. Can be called more than once to switch card sets. | 180 * Sets the cards used. Can be called more than once to switch card sets. |
178 * @param {!Array<!Element>} cards The individual viewable cards. | 181 * @param {!Array<!Element>} cards The individual viewable cards. |
179 * @param {number} index Index of the card to in the new set of cards to | 182 * @param {number} index Index of the card to in the new set of cards to |
180 * navigate to. | 183 * navigate to. |
181 */ | 184 */ |
182 setCards: function(cards, index) { | 185 setCards: function(cards, index) { |
183 assert(index >= 0 && index < cards.length, | 186 assert( |
| 187 index >= 0 && index < cards.length, |
184 'Invalid index in CardSlider#setCards'); | 188 'Invalid index in CardSlider#setCards'); |
185 this.cards_ = cards; | 189 this.cards_ = cards; |
186 | 190 |
187 this.updateCardWidths_(); | 191 this.updateCardWidths_(); |
188 this.updateSelectedCardAttributes_(); | 192 this.updateSelectedCardAttributes_(); |
189 | 193 |
190 // Jump to the given card index. | 194 // Jump to the given card index. |
191 this.selectCard(index, false, false, true); | 195 this.selectCard(index, false, false, true); |
192 }, | 196 }, |
193 | 197 |
(...skipping 23 matching lines...) Expand all Loading... |
217 */ | 221 */ |
218 updateCardWidths_: function() { | 222 updateCardWidths_: function() { |
219 for (var i = 0, card; card = this.cards_[i]; i++) | 223 for (var i = 0, card; card = this.cards_[i]; i++) |
220 card.style.width = this.cardWidth_ + 'px'; | 224 card.style.width = this.cardWidth_ + 'px'; |
221 }, | 225 }, |
222 | 226 |
223 /** | 227 /** |
224 * Returns the index of the current card. | 228 * Returns the index of the current card. |
225 * @return {number} index of the current card. | 229 * @return {number} index of the current card. |
226 */ | 230 */ |
227 get currentCard() { | 231 get currentCard() { return this.currentCard_; }, |
228 return this.currentCard_; | |
229 }, | |
230 | 232 |
231 /** | 233 /** |
232 * Allows setting the current card index. | 234 * Allows setting the current card index. |
233 * @param {number} index A new index to set the current index to. | 235 * @param {number} index A new index to set the current index to. |
234 * @return {number} The new index after having been set. | 236 * @return {number} The new index after having been set. |
235 */ | 237 */ |
236 set currentCard(index) { | 238 set currentCard(index) { return (this.currentCard_ = index); }, |
237 return (this.currentCard_ = index); | |
238 }, | |
239 | 239 |
240 /** | 240 /** |
241 * Returns the number of cards. | 241 * Returns the number of cards. |
242 * @return {number} number of cards. | 242 * @return {number} number of cards. |
243 */ | 243 */ |
244 get cardCount() { | 244 get cardCount() { return this.cards_.length; }, |
245 return this.cards_.length; | |
246 }, | |
247 | 245 |
248 /** | 246 /** |
249 * Returns the current card itself. | 247 * Returns the current card itself. |
250 * @return {!Element} the currently shown card. | 248 * @return {!Element} the currently shown card. |
251 */ | 249 */ |
252 get currentCardValue() { | 250 get currentCardValue() { return this.cards_[this.currentCard_]; }, |
253 return this.cards_[this.currentCard_]; | |
254 }, | |
255 | 251 |
256 /** | 252 /** |
257 * Returns the frame holding the cards. | 253 * Returns the frame holding the cards. |
258 * @return {Element} The frame used to position the cards. | 254 * @return {Element} The frame used to position the cards. |
259 */ | 255 */ |
260 get frame() { | 256 get frame() { return this.frame_; }, |
261 return this.frame_; | |
262 }, | |
263 | 257 |
264 /** | 258 /** |
265 * Handle horizontal scrolls to flip between pages. | 259 * Handle horizontal scrolls to flip between pages. |
266 * @private | 260 * @private |
267 */ | 261 */ |
268 onMouseWheel_: function(e) { | 262 onMouseWheel_: function(e) { |
269 if (e.wheelDeltaX == 0) | 263 if (e.wheelDeltaX == 0) |
270 return; | 264 return; |
271 | 265 |
272 // Continuous devices such as an Apple Touchpad or Apple MagicMouse will | 266 // Continuous devices such as an Apple Touchpad or Apple MagicMouse will |
273 // send arbitrary delta values. Conversly, standard mousewheels will | 267 // send arbitrary delta values. Conversly, standard mousewheels will |
274 // send delta values in increments of 120. (There is of course a small | 268 // send delta values in increments of 120. (There is of course a small |
275 // chance we mistake a continuous device for a non-continuous device. | 269 // chance we mistake a continuous device for a non-continuous device. |
276 // Unfortunately there isn't a better way to do this until real touch | 270 // Unfortunately there isn't a better way to do this until real touch |
277 // events are available to desktop clients.) | 271 // events are available to desktop clients.) |
278 var DISCRETE_DELTA = 120; | 272 var DISCRETE_DELTA = 120; |
279 if (e.wheelDeltaX % DISCRETE_DELTA) | 273 if (e.wheelDeltaX % DISCRETE_DELTA) |
280 this.mouseWheelIsContinuous_ = true; | 274 this.mouseWheelIsContinuous_ = true; |
281 | 275 |
282 if (this.mouseWheelIsContinuous_) { | 276 if (this.mouseWheelIsContinuous_) { |
283 // For continuous devices, detect a page swipe when the accumulated | 277 // For continuous devices, detect a page swipe when the accumulated |
284 // delta matches a pre-defined threshhold. After changing the page, | 278 // delta matches a pre-defined threshhold. After changing the page, |
285 // ignore wheel events for a short time before repeating this process. | 279 // ignore wheel events for a short time before repeating this process. |
286 if (this.mouseWheelCardSelected_) return; | 280 if (this.mouseWheelCardSelected_) |
| 281 return; |
287 this.mouseWheelScrollAmount_ += e.wheelDeltaX; | 282 this.mouseWheelScrollAmount_ += e.wheelDeltaX; |
288 if (Math.abs(this.mouseWheelScrollAmount_) >= 600) { | 283 if (Math.abs(this.mouseWheelScrollAmount_) >= 600) { |
289 var pagesToScroll = this.mouseWheelScrollAmount_ > 0 ? 1 : -1; | 284 var pagesToScroll = this.mouseWheelScrollAmount_ > 0 ? 1 : -1; |
290 if (!isRTL()) | 285 if (!isRTL()) |
291 pagesToScroll *= -1; | 286 pagesToScroll *= -1; |
292 var newCardIndex = this.currentCard + pagesToScroll; | 287 var newCardIndex = this.currentCard + pagesToScroll; |
293 newCardIndex = Math.min(this.cards_.length - 1, | 288 newCardIndex = |
294 Math.max(0, newCardIndex)); | 289 Math.min(this.cards_.length - 1, Math.max(0, newCardIndex)); |
295 this.selectCard(newCardIndex, true); | 290 this.selectCard(newCardIndex, true); |
296 this.mouseWheelCardSelected_ = true; | 291 this.mouseWheelCardSelected_ = true; |
297 } | 292 } |
298 } else { | 293 } else { |
299 // For discrete devices, consider each wheel tick a page change. | 294 // For discrete devices, consider each wheel tick a page change. |
300 var pagesToScroll = e.wheelDeltaX / DISCRETE_DELTA; | 295 var pagesToScroll = e.wheelDeltaX / DISCRETE_DELTA; |
301 if (!isRTL()) | 296 if (!isRTL()) |
302 pagesToScroll *= -1; | 297 pagesToScroll *= -1; |
303 var newCardIndex = this.currentCard + pagesToScroll; | 298 var newCardIndex = this.currentCard + pagesToScroll; |
304 newCardIndex = Math.min(this.cards_.length - 1, | 299 newCardIndex = |
305 Math.max(0, newCardIndex)); | 300 Math.min(this.cards_.length - 1, Math.max(0, newCardIndex)); |
306 this.selectCard(newCardIndex, true); | 301 this.selectCard(newCardIndex, true); |
307 } | 302 } |
308 | 303 |
309 // We got a mouse wheel event, so cancel any pending scroll wheel timeout. | 304 // We got a mouse wheel event, so cancel any pending scroll wheel timeout. |
310 if (this.scrollClearTimeout_ != null) | 305 if (this.scrollClearTimeout_ != null) |
311 clearTimeout(this.scrollClearTimeout_); | 306 clearTimeout(this.scrollClearTimeout_); |
312 // If we didn't use up all the scroll, hold onto it for a little bit, but | 307 // If we didn't use up all the scroll, hold onto it for a little bit, but |
313 // drop it after a delay. | 308 // drop it after a delay. |
314 if (this.mouseWheelScrollAmount_ != 0) { | 309 if (this.mouseWheelScrollAmount_ != 0) { |
315 this.scrollClearTimeout_ = | 310 this.scrollClearTimeout_ = |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 e.removedCard = card; | 451 e.removedCard = card; |
457 e.removedIndex = index; | 452 e.removedIndex = index; |
458 this.container_.dispatchEvent(e); | 453 this.container_.dispatchEvent(e); |
459 }, | 454 }, |
460 | 455 |
461 /** | 456 /** |
462 * This re-syncs the transform that's used to position the frame in | 457 * This re-syncs the transform that's used to position the frame in |
463 * the likely event it needs to be updated by a card being inserted or | 458 * the likely event it needs to be updated by a card being inserted or |
464 * removed in the flow. | 459 * removed in the flow. |
465 */ | 460 */ |
466 repositionFrame: function() { | 461 repositionFrame: function() { this.transformToCurrentCard_(); }, |
467 this.transformToCurrentCard_(); | |
468 }, | |
469 | 462 |
470 /** | 463 /** |
471 * Checks the the given |index| exists in this.cards_. | 464 * Checks the the given |index| exists in this.cards_. |
472 * @param {number} index An index to check. | 465 * @param {number} index An index to check. |
473 * @private | 466 * @private |
474 */ | 467 */ |
475 assertValidIndex_: function(index) { | 468 assertValidIndex_: function(index) { |
476 assert(index >= 0 && index < this.cards_.length); | 469 assert(index >= 0 && index < this.cards_.length); |
477 }, | 470 }, |
478 | 471 |
479 /** | 472 /** |
480 * Selects a new card, ensuring that it is a valid index, transforming the | 473 * Selects a new card, ensuring that it is a valid index, transforming the |
481 * view and possibly calling the change card callback. | 474 * view and possibly calling the change card callback. |
482 * @param {number} newCardIndex Index of card to show. | 475 * @param {number} newCardIndex Index of card to show. |
483 * @param {boolean=} opt_animate If true will animate transition from | 476 * @param {boolean=} opt_animate If true will animate transition from |
484 * current position to new position. | 477 * current position to new position. |
485 * @param {boolean=} opt_dontNotify If true, don't tell subscribers that | 478 * @param {boolean=} opt_dontNotify If true, don't tell subscribers that |
486 * we've changed cards. | 479 * we've changed cards. |
487 * @param {boolean=} opt_forceChange If true, ignore if the card already | 480 * @param {boolean=} opt_forceChange If true, ignore if the card already |
488 * selected. | 481 * selected. |
489 */ | 482 */ |
490 selectCard: function(newCardIndex, | 483 selectCard: function( |
491 opt_animate, | 484 newCardIndex, opt_animate, opt_dontNotify, opt_forceChange) { |
492 opt_dontNotify, | |
493 opt_forceChange) { | |
494 this.assertValidIndex_(newCardIndex); | 485 this.assertValidIndex_(newCardIndex); |
495 | 486 |
496 var previousCard = this.currentCardValue; | 487 var previousCard = this.currentCardValue; |
497 var isChangingCard = | 488 var isChangingCard = |
498 !this.cards_[newCardIndex].classList.contains('selected-card'); | 489 !this.cards_[newCardIndex].classList.contains('selected-card'); |
499 | 490 |
500 if (typeof opt_forceChange != 'undefined' && opt_forceChange) | 491 if (typeof opt_forceChange != 'undefined' && opt_forceChange) |
501 isChangingCard = true; | 492 isChangingCard = true; |
502 | 493 |
503 if (isChangingCard) { | 494 if (isChangingCard) { |
504 this.currentCard_ = newCardIndex; | 495 this.currentCard_ = newCardIndex; |
505 this.updateSelectedCardAttributes_(); | 496 this.updateSelectedCardAttributes_(); |
506 } | 497 } |
507 | 498 |
508 var willTransitionHappen = this.transformToCurrentCard_(opt_animate); | 499 var willTransitionHappen = this.transformToCurrentCard_(opt_animate); |
509 | 500 |
510 if (isChangingCard && !opt_dontNotify) { | 501 if (isChangingCard && !opt_dontNotify) { |
511 var event = document.createEvent('Event'); | 502 var event = document.createEvent('Event'); |
512 event.initEvent('cardSlider:card_changed', true, true); | 503 event.initEvent('cardSlider:card_changed', true, true); |
513 event.cardSlider = this; | 504 event.cardSlider = this; |
514 event.wasAnimated = !!opt_animate; | 505 event.wasAnimated = !!opt_animate; |
515 this.container_.dispatchEvent(event); | 506 this.container_.dispatchEvent(event); |
516 | 507 |
517 // We also dispatch an event on the cards themselves. | 508 // We also dispatch an event on the cards themselves. |
518 if (previousCard) { | 509 if (previousCard) { |
519 cr.dispatchSimpleEvent(previousCard, 'carddeselected', | 510 cr.dispatchSimpleEvent(previousCard, 'carddeselected', true, true); |
520 true, true); | |
521 } | 511 } |
522 cr.dispatchSimpleEvent(this.currentCardValue, 'cardselected', | 512 cr.dispatchSimpleEvent( |
523 true, true); | 513 this.currentCardValue, 'cardselected', true, true); |
524 } | 514 } |
525 | 515 |
526 // If we're not changing, animated, or transitioning, fire a | 516 // If we're not changing, animated, or transitioning, fire a |
527 // cardSlider:card_change_ended event right away. | 517 // cardSlider:card_change_ended event right away. |
528 if ((!isChangingCard || !opt_animate || !willTransitionHappen) && | 518 if ((!isChangingCard || !opt_animate || !willTransitionHappen) && |
529 !opt_dontNotify) { | 519 !opt_dontNotify) { |
530 this.fireChangeEndedEvent_(false); | 520 this.fireChangeEndedEvent_(false); |
531 } | 521 } |
532 }, | 522 }, |
533 | 523 |
(...skipping 25 matching lines...) Expand all Loading... |
559 // If there's no change, return something to let the caller know there | 549 // If there's no change, return something to let the caller know there |
560 // won't be a transition occuring. | 550 // won't be a transition occuring. |
561 if (prevLeft == this.currentLeft_ && this.deltaX_ == 0) | 551 if (prevLeft == this.currentLeft_ && this.deltaX_ == 0) |
562 return false; | 552 return false; |
563 | 553 |
564 // Animate to the current card, which will either transition if the | 554 // Animate to the current card, which will either transition if the |
565 // current card is new, or reset the existing card if we didn't drag | 555 // current card is new, or reset the existing card if we didn't drag |
566 // enough to change cards. | 556 // enough to change cards. |
567 var transition = ''; | 557 var transition = ''; |
568 if (opt_animate) { | 558 if (opt_animate) { |
569 transition = 'transform ' + CardSlider.TRANSITION_TIME_ + | 559 transition = |
570 'ms ease-in-out'; | 560 'transform ' + CardSlider.TRANSITION_TIME_ + 'ms ease-in-out'; |
571 } | 561 } |
572 this.container_.style.WebkitTransition = transition; | 562 this.container_.style.WebkitTransition = transition; |
573 this.translateTo_(this.currentLeft_); | 563 this.translateTo_(this.currentLeft_); |
574 | 564 |
575 return true; | 565 return true; |
576 }, | 566 }, |
577 | 567 |
578 /** | 568 /** |
579 * Moves the view to the specified position. | 569 * Moves the view to the specified position. |
580 * @param {number} x Horizontal position to move to. | 570 * @param {number} x Horizontal position to move to. |
(...skipping 10 matching lines...) Expand all Loading... |
591 | 581 |
592 /* Touch ******************************************************************/ | 582 /* Touch ******************************************************************/ |
593 | 583 |
594 /** | 584 /** |
595 * Clear any transition that is in progress and enable dragging for the | 585 * Clear any transition that is in progress and enable dragging for the |
596 * touch. | 586 * touch. |
597 * @param {!Event} e The TouchHandler event. | 587 * @param {!Event} e The TouchHandler event. |
598 * @private | 588 * @private |
599 */ | 589 */ |
600 onTouchStart_: function(e) { | 590 onTouchStart_: function(e) { |
601 e = /** @type {!cr.ui.TouchHandler.Event} */(e); | 591 e = /** @type {!cr.ui.TouchHandler.Event} */ (e); |
602 this.container_.style.WebkitTransition = ''; | 592 this.container_.style.WebkitTransition = ''; |
603 e.enableDrag = true; | 593 e.enableDrag = true; |
604 }, | 594 }, |
605 | 595 |
606 /** | 596 /** |
607 * Tell the TouchHandler that dragging is acceptable when the user begins by | 597 * Tell the TouchHandler that dragging is acceptable when the user begins by |
608 * scrolling horizontally and there is more than one card to slide. | 598 * scrolling horizontally and there is more than one card to slide. |
609 * @param {!Event} e The TouchHandler event. | 599 * @param {!Event} e The TouchHandler event. |
610 * @private | 600 * @private |
611 */ | 601 */ |
612 onDragStart_: function(e) { | 602 onDragStart_: function(e) { |
613 e = /** @type {!cr.ui.TouchHandler.Event} */(e); | 603 e = /** @type {!cr.ui.TouchHandler.Event} */ (e); |
614 e.enableDrag = this.cardCount > 1 && Math.abs(e.dragDeltaX) > | 604 e.enableDrag = |
615 Math.abs(e.dragDeltaY); | 605 this.cardCount > 1 && Math.abs(e.dragDeltaX) > Math.abs(e.dragDeltaY); |
616 }, | 606 }, |
617 | 607 |
618 /** | 608 /** |
619 * On each drag move event reposition the container appropriately so the | 609 * On each drag move event reposition the container appropriately so the |
620 * cards look like they are sliding. | 610 * cards look like they are sliding. |
621 * @param {!Event} e The TouchHandler event. | 611 * @param {!Event} e The TouchHandler event. |
622 * @private | 612 * @private |
623 */ | 613 */ |
624 onDragMove_: function(e) { | 614 onDragMove_: function(e) { |
625 e = /** @type {!cr.ui.TouchHandler.Event} */(e); | 615 e = /** @type {!cr.ui.TouchHandler.Event} */ (e); |
626 var deltaX = e.dragDeltaX; | 616 var deltaX = e.dragDeltaX; |
627 // If dragging beyond the first or last card then apply a backoff so the | 617 // If dragging beyond the first or last card then apply a backoff so the |
628 // dragging feels stickier than usual. | 618 // dragging feels stickier than usual. |
629 if (!this.currentCard && deltaX > 0 || | 619 if (!this.currentCard && deltaX > 0 || |
630 this.currentCard == (this.cards_.length - 1) && deltaX < 0) { | 620 this.currentCard == (this.cards_.length - 1) && deltaX < 0) { |
631 deltaX /= 2; | 621 deltaX /= 2; |
632 } | 622 } |
633 this.translateTo_(this.currentLeft_ + deltaX); | 623 this.translateTo_(this.currentLeft_ + deltaX); |
634 }, | 624 }, |
635 | 625 |
636 /** | 626 /** |
637 * On drag end events we may want to transition to another card, depending | 627 * On drag end events we may want to transition to another card, depending |
638 * on the ending position of the drag and the velocity of the drag. | 628 * on the ending position of the drag and the velocity of the drag. |
639 * @param {!Event} e The TouchHandler event. | 629 * @param {!Event} e The TouchHandler event. |
640 * @private | 630 * @private |
641 */ | 631 */ |
642 onDragEnd_: function(e) { | 632 onDragEnd_: function(e) { |
643 e = /** @type {!cr.ui.TouchHandler.Event} */(e); | 633 e = /** @type {!cr.ui.TouchHandler.Event} */ (e); |
644 var deltaX = e.dragDeltaX; | 634 var deltaX = e.dragDeltaX; |
645 var velocity = this.touchHandler_.getEndVelocity().x; | 635 var velocity = this.touchHandler_.getEndVelocity().x; |
646 var newX = this.currentLeft_ + deltaX; | 636 var newX = this.currentLeft_ + deltaX; |
647 var newCardIndex = Math.round(-newX / this.cardWidth_); | 637 var newCardIndex = Math.round(-newX / this.cardWidth_); |
648 | 638 |
649 if (newCardIndex == this.currentCard && Math.abs(velocity) > | 639 if (newCardIndex == this.currentCard && |
650 CardSlider.TRANSITION_VELOCITY_THRESHOLD_) { | 640 Math.abs(velocity) > CardSlider.TRANSITION_VELOCITY_THRESHOLD_) { |
651 // The drag wasn't far enough to change cards but the velocity was | 641 // The drag wasn't far enough to change cards but the velocity was |
652 // high enough to transition anyways. If the velocity is to the left | 642 // high enough to transition anyways. If the velocity is to the left |
653 // (negative) then the user wishes to go right (card + 1). | 643 // (negative) then the user wishes to go right (card + 1). |
654 newCardIndex += velocity > 0 ? -1 : 1; | 644 newCardIndex += velocity > 0 ? -1 : 1; |
655 } | 645 } |
656 // Ensure that the new card index is valid. The new card index could be | 646 // Ensure that the new card index is valid. The new card index could be |
657 // invalid if a swipe suggests scrolling off the end of the list of | 647 // invalid if a swipe suggests scrolling off the end of the list of |
658 // cards. | 648 // cards. |
659 if (newCardIndex < 0) | 649 if (newCardIndex < 0) |
660 newCardIndex = 0; | 650 newCardIndex = 0; |
661 else if (newCardIndex >= this.cardCount) | 651 else if (newCardIndex >= this.cardCount) |
662 newCardIndex = this.cardCount - 1; | 652 newCardIndex = this.cardCount - 1; |
663 this.selectCard(newCardIndex, /* animate */ true); | 653 this.selectCard(newCardIndex, /* animate */ true); |
664 }, | 654 }, |
665 | 655 |
666 /** | 656 /** |
667 * Cancel any current touch/slide as if we saw a touch end | 657 * Cancel any current touch/slide as if we saw a touch end |
668 */ | 658 */ |
669 cancelTouch: function() { | 659 cancelTouch: function() { |
670 // Stop listening to any current touch | 660 // Stop listening to any current touch |
671 this.touchHandler_.cancelTouch(); | 661 this.touchHandler_.cancelTouch(); |
672 | 662 |
673 // Ensure we're at a card bounary | 663 // Ensure we're at a card bounary |
674 this.transformToCurrentCard_(true); | 664 this.transformToCurrentCard_(true); |
675 }, | 665 }, |
676 }; | 666 }; |
677 | 667 |
678 return { | 668 return {CardSlider: CardSlider}; |
679 CardSlider: CardSlider | |
680 }; | |
681 }); | 669 }); |
OLD | NEW |