OLD | NEW |
(Empty) | |
| 1 <!-- |
| 2 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 3 // Use of this source code is governed by a BSD-style license that can be |
| 4 // found in the LICENSE file. |
| 5 --> |
| 6 <import src="/sky/framework/sky-element/sky-element.sky" as="SkyElement" /> |
| 7 |
| 8 <sky-element |
| 9 name="sky-scrollable" |
| 10 on-gesturescrollstart="handleScrollStart_" |
| 11 on-gesturescrollend="handleScrollEnd_" |
| 12 on-gesturescrollupdate="handleScrollUpdate_" |
| 13 on-gestureflingstart="handleFlingStart_" |
| 14 on-gestureflingcancel="handleFlingCancel_"> |
| 15 <template> |
| 16 <style> |
| 17 :host { |
| 18 overflow: hidden; |
| 19 } |
| 20 #scrollable { |
| 21 transform: translateY(0); |
| 22 } |
| 23 </style> |
| 24 <div id="scrollable"> |
| 25 <content /> |
| 26 </div> |
| 27 </template> |
| 28 <script> |
| 29 // TODO(abarth): Move the fling curve to a separate module. |
| 30 var kFlingFriction = 0.9; |
| 31 var kFlingVelocityMin = 1; |
| 32 |
| 33 module.exports = class extends SkyElement { |
| 34 created() { |
| 35 this.scrollable_ = null; |
| 36 this.scrollOffset_ = 0; |
| 37 this.flingVelocity_ = 0; |
| 38 this.flingAnimationId_ = null; |
| 39 } |
| 40 |
| 41 shadowRootReady() { |
| 42 this.scrollable_ = this.shadowRoot.getElementById('scrollable'); |
| 43 } |
| 44 |
| 45 scrollBy(scrollDelta) { |
| 46 var offset = Math.max(0, Math.min(this.scrollable_.offsetHeight, this.scroll
Offset_ + scrollDelta)); |
| 47 if (offset == this.scrollOffset_) |
| 48 return false; |
| 49 this.scrollOffset_ = offset; |
| 50 this.applyScrollOffset_(); |
| 51 return true; |
| 52 } |
| 53 |
| 54 applyScrollOffset_() { |
| 55 var transform = 'translateY(' + -this.scrollOffset_.toFixed(2) + 'px)'; |
| 56 this.scrollable_.style.transform = transform; |
| 57 } |
| 58 |
| 59 scheduleFlingTick_() { |
| 60 this.flingAnimationId_ = requestAnimationFrame(this.tickFling_.bind(this)); |
| 61 } |
| 62 |
| 63 tickFling_() { |
| 64 this.flingAnimationId_ = null; |
| 65 if (!this.scrollBy(this.flingVelocity_)) { |
| 66 this.flingVelocity_ = 0; |
| 67 return; |
| 68 } |
| 69 var velocity = this.flingVelocity_ * kFlingFriction; |
| 70 if (velocity < kFlingVelocityMin) |
| 71 velocity = 0; |
| 72 this.flingVelocity_ = velocity; |
| 73 if (velocity) |
| 74 this.scheduleFlingTick_(); |
| 75 } |
| 76 |
| 77 handleScrollStart_(event) { |
| 78 } |
| 79 |
| 80 handleScrollEnd_(event) { |
| 81 } |
| 82 |
| 83 handleScrollUpdate_(event) { |
| 84 this.scrollBy(-event.dy); |
| 85 } |
| 86 |
| 87 handleFlingStart_(event) { |
| 88 this.flingVelocity_ = -event.velocityY; |
| 89 this.scheduleFlingTick_(); |
| 90 } |
| 91 |
| 92 handleFlingCancel_(event) { |
| 93 if (!this.flingAnimationId_) |
| 94 return; |
| 95 cancelAnimationFrame(this.flingAnimationId_); |
| 96 this.flingVelocity_ = 0; |
| 97 this.flingAnimationId_ = null; |
| 98 } |
| 99 }.register(); |
| 100 </script> |
| 101 </sky-element> |
OLD | NEW |