Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: sky/framework/sky-scrollable.sky

Issue 950603002: Port sky-scrollable to Dart (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: less setAttributes Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/framework/sky-element.sky ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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-element/sky-element.sky" as="SkyElement" /> 6 <import src="sky-element.sky" />
7 <import src="fling-curve.sky" as="FlingCurve" />
8 7
9 <sky-element 8 <sky-element>
10 name="sky-scrollable"
11 on-gesturescrollstart="handleScrollStart_"
12 on-gesturescrollend="handleScrollEnd_"
13 on-gesturescrollupdate="handleScrollUpdate_"
14 on-gestureflingstart="handleFlingStart_"
15 on-gestureflingcancel="handleFlingCancel_"
16 on-wheel="handleWheel_">
17 <template> 9 <template>
18 <style> 10 <style>
19 :host { 11 :host {
20 overflow: hidden; 12 overflow: hidden;
21 position: relative; 13 position: relative;
22 } 14 }
23 #scrollable { 15 #scrollable {
24 transform: translateY(0); 16 transform: translateY(0);
25 } 17 }
26 #vbar { 18 #vbar {
27 position: absolute; 19 position: absolute;
28 right: 0; 20 right: 0;
29 width: 3px; 21 width: 3px;
30 background-color: lightgray; 22 background-color: lightgray;
31 pointer-events: none; 23 pointer-events: none;
32 top: 0; 24 top: 0;
33 height: 0; 25 height: 0;
34 will-change: opacity; 26 will-change: opacity;
35 opacity: 0; 27 opacity: 0;
36 transition: opacity 0.2s ease-in-out; 28 transition: opacity 0.2s ease-in-out;
37 } 29 }
38 </style> 30 </style>
39 <div id="scrollable"> 31 <div id="scrollable">
40 <content /> 32 <content />
41 </div> 33 </div>
42 <div id="vbar" /> 34 <div id="vbar" />
43 </template> 35 </template>
44 <script> 36 <script>
45 module.exports = class extends SkyElement { 37 import "dart:math" as math;
46 created() { 38 import "dart:sky";
47 this.scrollable_ = null; 39 import "fling-curve.dart";
48 this.vbar_ = null; 40
49 this.scrollOffset_ = 0; 41 @Tagname('sky-scrollable')
50 this.flingCurve_ = null; 42 class SkyScrollable extends SkyElement {
51 this.flingAnimationId_ = null; 43 Element _scrollable;
44 Element _vbar;
45 double _scrollOffset = 0.0;
46 FlingCurve _flingCurve;
47 int _flingAnimationId;
48
49 SkyScrollable() {
50 addEventListener('gesturescrollstart', _handleScrollStart);
51 addEventListener('gesturescrollend', _handleScrollEnd);
52 addEventListener('gesturescrollupdate', _handleScrollUpdate);
53 addEventListener('gestureflingstart', _handleFlingStart);
54 addEventListener('gestureflingcancel', _handleFlingCancel);
55 addEventListener('wheel', _handleWheel);
52 } 56 }
53 57
54 shadowRootReady() { 58 void shadowRootReady() {
55 this.scrollable_ = this.shadowRoot.getElementById('scrollable'); 59 _scrollable = shadowRoot.getElementById('scrollable');
56 this.vbar_ = this.shadowRoot.getElementById('vbar'); 60 _vbar = shadowRoot.getElementById('vbar');
57 } 61 }
58 62
59 get scrollOffset() { 63 double get scrollOffset => _scrollOffset;
60 return this.scrollOffset_; 64
65 set scrollOffset(double value) {
66 // TODO(abarth): Can we get these values without forcing a synchronous layou t?
67 double outerHeight = clientHeight.toDouble();
68 double innerHeight = _scrollable.clientHeight.toDouble();
69 double scrollRange = innerHeight - outerHeight;
70 double newScrollOffset = math.max(0.0, math.min(scrollRange, value));
71 if (newScrollOffset == _scrollOffset)
72 return;
73 _scrollOffset = newScrollOffset;
74 String transform = 'translateY(${(-_scrollOffset).toStringAsFixed(2)}px)';
75 _scrollable.style['transform'] = transform;
76
77 double topPercent = newScrollOffset / innerHeight * 100.0;
78 double heightPercent = outerHeight / innerHeight * 100.0;
79 _vbar.style['top'] = '${topPercent}%';
80 _vbar.style['height'] = '${heightPercent}%';
61 } 81 }
62 82
63 set scrollOffset(value) { 83 bool scrollBy(double scrollDelta) {
64 // TODO(abarth): Can we get these values without forcing a synchronous layou t? 84 double oldScrollOffset = _scrollOffset;
65 var outerHeight = this.clientHeight; 85 scrollOffset += scrollDelta;
66 var innerHeight = this.scrollable_.clientHeight; 86 return _scrollOffset != oldScrollOffset;
67 var scrollRange = innerHeight - outerHeight;
68 var newScrollOffset = Math.max(0, Math.min(scrollRange, value));
69 if (newScrollOffset == this.scrollOffset_)
70 return;
71 this.scrollOffset_ = newScrollOffset;
72 var transform = 'translateY(' + -this.scrollOffset_.toFixed(2) + 'px)';
73 this.scrollable_.style.transform = transform;
74
75 var topPercent = newScrollOffset / innerHeight * 100;
76 var heightPercent = outerHeight / innerHeight * 100;
77 this.vbar_.style.top = topPercent + '%';
78 this.vbar_.style.height = heightPercent + '%';
79 } 87 }
80 88
81 scrollBy(scrollDelta) { 89 void _scheduleFlingUpdate() {
82 var oldScrollOffset = this.scrollOffset_; 90 _flingAnimationId = window.requestAnimationFrame(_updateFling);
83 this.scrollOffset += scrollDelta;
84 return this.scrollOffset_ != oldScrollOffset;
85 } 91 }
86 92
87 scheduleFlingUpdate_() { 93 void _stopFling() {
88 this.flingAnimationId_ = requestAnimationFrame(this.updateFling_.bind(this)) ; 94 window.cancelAnimationFrame(_flingAnimationId);
95 _flingCurve = null;
96 _flingAnimationId = null;
97 _vbar.style['opacity'] = '0';
89 } 98 }
90 99
91 stopFling_() { 100 void _updateFling(double timeStamp) {
92 cancelAnimationFrame(this.flingAnimationId_); 101 double scrollDelta = _flingCurve.update(timeStamp);
93 this.flingCurve_ = null; 102 if (scrollDelta == 0.0 || !scrollBy(scrollDelta))
94 this.flingAnimationId_ = null; 103 _stopFling();
95 this.vbar_.style.opacity = 0; 104 else
105 _scheduleFlingUpdate();
96 } 106 }
97 107
98 updateFling_(timeStamp) { 108 void _handleScrollStart(_) {
99 var scrollDelta = this.flingCurve_.update(timeStamp); 109 _vbar.style['opacity'] = '1';
100 if (!scrollDelta || !this.scrollBy(scrollDelta))
101 return this.stopFling_();
102 this.scheduleFlingUpdate_();
103 } 110 }
104 111
105 handleScrollStart_(event) { 112 void _handleScrollEnd(_) {
106 this.vbar_.style.opacity = 1; 113 _vbar.style['opacity'] = '0';
107 } 114 }
108 115
109 handleScrollEnd_(event) { 116 void _handleScrollUpdate(GestureEvent event) {
110 this.vbar_.style.opacity = 0; 117 scrollBy(-event.dy);
111 } 118 }
112 119
113 handleScrollUpdate_(event) { 120 void _handleFlingStart(GestureEvent event) {
114 this.scrollBy(-event.dy); 121 _flingCurve = new FlingCurve(-event.velocityY, event.timeStamp);
122 _scheduleFlingUpdate();
115 } 123 }
116 124
117 handleFlingStart_(event) { 125 void _handleFlingCancel(_) {
118 this.flingCurve_ = new FlingCurve(-event.velocityY, event.timeStamp); 126 _stopFling();
119 this.scheduleFlingUpdate_();
120 } 127 }
121 128
122 handleFlingCancel_(event) { 129 void _handleWheel(WheelEvent event) {
123 this.stopFling_(); 130 scrollBy(-event.offsetY);
124 } 131 }
132 }
125 133
126 handleWheel_(event) { 134 _init(script) => register(script, SkyScrollable);
127 this.scrollBy(-event.offsetY);
128 }
129 }.register();
130 </script> 135 </script>
131 </sky-element> 136 </sky-element>
OLDNEW
« no previous file with comments | « sky/framework/sky-element.sky ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698