Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 <!-- | 1 <!-- |
| 2 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 3 // Use of this source code is governed by a BSD-style license that can be |
| 4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
| 5 --> | 5 --> |
| 6 <import src="/sky/framework/sky-element/sky-element.sky" as="SkyElement" /> | 6 <import src="/sky/framework/sky-element/sky-element.sky" as="SkyElement" /> |
| 7 <import src="/sky/framework/fling-curve.sky" as="FlingCurve" /> | 7 <import src="/sky/framework/fling-curve.sky" as="FlingCurve" /> |
| 8 | 8 |
| 9 <sky-element | 9 <sky-element |
| 10 name="sky-scrollable" | 10 name="sky-scrollable" |
| 11 on-gesturescrollstart="handleScrollStart_" | 11 on-gesturescrollstart="handleScrollStart_" |
| 12 on-gesturescrollend="handleScrollEnd_" | 12 on-gesturescrollend="handleScrollEnd_" |
| 13 on-gesturescrollupdate="handleScrollUpdate_" | 13 on-gesturescrollupdate="handleScrollUpdate_" |
| 14 on-gestureflingstart="handleFlingStart_" | 14 on-gestureflingstart="handleFlingStart_" |
| 15 on-gestureflingcancel="handleFlingCancel_"> | 15 on-gestureflingcancel="handleFlingCancel_"> |
| 16 <template> | 16 <template> |
| 17 <style> | 17 <style> |
| 18 :host { | 18 :host { |
| 19 overflow: hidden; | 19 overflow: hidden; |
| 20 position: relative; | |
| 20 } | 21 } |
| 21 #scrollable { | 22 #scrollable { |
| 22 transform: translateY(0); | 23 transform: translateY(0); |
| 23 } | 24 } |
| 25 #vbar { | |
| 26 position: absolute; | |
| 27 right: 0; | |
| 28 width: 3px; | |
| 29 background-color: lightgray; | |
| 30 top: 0; | |
| 31 height: 0; | |
| 32 } | |
| 24 </style> | 33 </style> |
| 34 <div id="vbar" /> | |
| 25 <div id="scrollable"> | 35 <div id="scrollable"> |
| 26 <content /> | 36 <content /> |
| 27 </div> | 37 </div> |
| 28 </template> | 38 </template> |
| 29 <script> | 39 <script> |
| 40 const kScrollbarFadeDurationMS = 300; | |
| 41 | |
| 30 module.exports = class extends SkyElement { | 42 module.exports = class extends SkyElement { |
| 31 created() { | 43 created() { |
| 32 this.scrollable_ = null; | 44 this.scrollable_ = null; |
| 45 this.vbar_ = null; | |
| 33 this.scrollOffset_ = 0; | 46 this.scrollOffset_ = 0; |
| 34 this.flingCurve_ = null; | 47 this.flingCurve_ = null; |
| 35 this.flingAnimationId_ = null; | 48 this.flingAnimationId_ = null; |
| 36 } | 49 } |
| 37 | 50 |
| 38 shadowRootReady() { | 51 shadowRootReady() { |
| 39 this.scrollable_ = this.shadowRoot.getElementById('scrollable'); | 52 this.scrollable_ = this.shadowRoot.getElementById('scrollable'); |
| 53 this.vbar_ = this.shadowRoot.getElementById('vbar'); | |
| 54 } | |
| 55 | |
| 56 get scrollOffset() { | |
| 57 return this.scrollOffset_; | |
| 58 } | |
| 59 | |
| 60 set scrollOffset(value) { | |
| 61 // TODO(abarth): Can we get these values without forcing a synchronous layou t? | |
|
ojan
2015/01/27 05:32:25
We should add apis that give you stale values and
abarth-chromium
2015/01/27 05:36:39
Yeah, it seems fine to use stale values here. I a
abarth-chromium
2015/01/27 05:36:39
Yeah, it seems fine to use stale values here. I a
| |
| 62 var outerHeight = this.clientHeight; | |
| 63 var innerHeight = this.scrollable_.clientHeight; | |
| 64 var scrollRange = innerHeight - outerHeight; | |
| 65 var newScrollOffset = Math.max(0, Math.min(scrollRange, value)); | |
| 66 if (newScrollOffset == this.scrollOffset_) | |
| 67 return; | |
| 68 this.scrollOffset_ = newScrollOffset; | |
| 69 var transform = 'translateY(' + -this.scrollOffset_.toFixed(2) + 'px)'; | |
| 70 this.scrollable_.style.transform = transform; | |
| 71 | |
| 72 var topPercent = newScrollOffset / innerHeight * 100; | |
| 73 var heightPercent = outerHeight / innerHeight * 100; | |
| 74 this.vbar_.style.top = topPercent + '%'; | |
| 75 this.vbar_.style.height = heightPercent + '%'; | |
|
ojan
2015/01/27 05:32:25
This won't work if the scrollable's height is auto
abarth-chromium
2015/01/27 05:36:39
Yeah. This should work as long as you don't chang
| |
| 40 } | 76 } |
| 41 | 77 |
| 42 scrollBy(scrollDelta) { | 78 scrollBy(scrollDelta) { |
| 43 var scrollHeight = this.scrollable_.clientHeight - this.clientHeight; | 79 var oldScrollOffset = this.scrollOffset_; |
| 44 var offset = Math.max(0, Math.min(scrollHeight, this.scrollOffset_ + scrollD elta)); | 80 this.scrollOffset += scrollDelta; |
| 45 if (offset == this.scrollOffset_) | 81 return this.scrollOffset_ != oldScrollOffset; |
| 46 return false; | |
| 47 this.scrollOffset_ = offset; | |
| 48 this.applyScrollOffset_(); | |
| 49 return true; | |
| 50 } | |
| 51 | |
| 52 applyScrollOffset_() { | |
| 53 var transform = 'translateY(' + -this.scrollOffset_.toFixed(2) + 'px)'; | |
| 54 this.scrollable_.style.transform = transform; | |
| 55 } | 82 } |
| 56 | 83 |
| 57 scheduleFlingUpdate_() { | 84 scheduleFlingUpdate_() { |
| 58 this.flingAnimationId_ = requestAnimationFrame(this.updateFling_.bind(this)) ; | 85 this.flingAnimationId_ = requestAnimationFrame(this.updateFling_.bind(this)) ; |
| 59 } | 86 } |
| 60 | 87 |
| 61 stopFling_() { | 88 stopFling_() { |
| 62 cancelAnimationFrame(this.flingAnimationId_); | 89 cancelAnimationFrame(this.flingAnimationId_); |
| 63 this.flingCurve_ = null; | 90 this.flingCurve_ = null; |
| 64 this.flingAnimationId_ = null; | 91 this.flingAnimationId_ = null; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 85 this.flingCurve_ = new FlingCurve(-event.velocityY, event.timeStamp); | 112 this.flingCurve_ = new FlingCurve(-event.velocityY, event.timeStamp); |
| 86 this.scheduleFlingUpdate_(); | 113 this.scheduleFlingUpdate_(); |
| 87 } | 114 } |
| 88 | 115 |
| 89 handleFlingCancel_(event) { | 116 handleFlingCancel_(event) { |
| 90 this.stopFling_(); | 117 this.stopFling_(); |
| 91 } | 118 } |
| 92 }.register(); | 119 }.register(); |
| 93 </script> | 120 </script> |
| 94 </sky-element> | 121 </sky-element> |
| OLD | NEW |