| 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 |