Index: sky/framework/sky-scrollable.sky |
diff --git a/sky/framework/sky-scrollable.sky b/sky/framework/sky-scrollable.sky |
index 9e369196a98147f67806b043c9c683c8706830ce..e0292d1d1ca621ca965debd77fd7f49ef17e4004 100644 |
--- a/sky/framework/sky-scrollable.sky |
+++ b/sky/framework/sky-scrollable.sky |
@@ -3,17 +3,9 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
--> |
-<import src="sky-element/sky-element.sky" as="SkyElement" /> |
-<import src="fling-curve.sky" as="FlingCurve" /> |
- |
-<sky-element |
- name="sky-scrollable" |
- on-gesturescrollstart="handleScrollStart_" |
- on-gesturescrollend="handleScrollEnd_" |
- on-gesturescrollupdate="handleScrollUpdate_" |
- on-gestureflingstart="handleFlingStart_" |
- on-gestureflingcancel="handleFlingCancel_" |
- on-wheel="handleWheel_"> |
+<import src="sky-element.sky" /> |
+ |
+<sky-element> |
<template> |
<style> |
:host { |
@@ -42,90 +34,103 @@ |
<div id="vbar" /> |
</template> |
<script> |
-module.exports = class extends SkyElement { |
- created() { |
- this.scrollable_ = null; |
- this.vbar_ = null; |
- this.scrollOffset_ = 0; |
- this.flingCurve_ = null; |
- this.flingAnimationId_ = null; |
- } |
+import "dart:math" as math; |
+import "dart:sky"; |
+import "fling-curve.dart"; |
+ |
+@Tagname('sky-scrollable') |
+class SkyScrollable extends SkyElement { |
+ Element _scrollable; |
+ Element _vbar; |
+ double _scrollOffset = 0.0; |
+ FlingCurve _flingCurve; |
+ int _flingAnimationId; |
- shadowRootReady() { |
- this.scrollable_ = this.shadowRoot.getElementById('scrollable'); |
- this.vbar_ = this.shadowRoot.getElementById('vbar'); |
+ SkyScrollable() { |
+ addEventListener('gesturescrollstart', _handleScrollStart); |
+ addEventListener('gesturescrollend', _handleScrollEnd); |
+ addEventListener('gesturescrollupdate', _handleScrollUpdate); |
+ addEventListener('gestureflingstart', _handleFlingStart); |
+ addEventListener('gestureflingcancel', _handleFlingCancel); |
+ addEventListener('wheel', _handleWheel); |
} |
- get scrollOffset() { |
- return this.scrollOffset_; |
+ void shadowRootReady() { |
+ _scrollable = shadowRoot.getElementById('scrollable'); |
+ _vbar = shadowRoot.getElementById('vbar'); |
} |
- set scrollOffset(value) { |
+ double get scrollOffset => _scrollOffset; |
+ |
+ set scrollOffset(double value) { |
// TODO(abarth): Can we get these values without forcing a synchronous layout? |
- var outerHeight = this.clientHeight; |
- var innerHeight = this.scrollable_.clientHeight; |
- var scrollRange = innerHeight - outerHeight; |
- var newScrollOffset = Math.max(0, Math.min(scrollRange, value)); |
- if (newScrollOffset == this.scrollOffset_) |
+ double outerHeight = clientHeight.toDouble(); |
+ double innerHeight = _scrollable.clientHeight.toDouble(); |
+ double scrollRange = innerHeight - outerHeight; |
+ double newScrollOffset = math.max(0.0, math.min(scrollRange, value)); |
+ if (newScrollOffset == _scrollOffset) |
return; |
- this.scrollOffset_ = newScrollOffset; |
- var transform = 'translateY(' + -this.scrollOffset_.toFixed(2) + 'px)'; |
- this.scrollable_.style.transform = transform; |
+ _scrollOffset = newScrollOffset; |
+ String transform = 'translateY(${(-_scrollOffset).toStringAsFixed(2)}px)'; |
+ _scrollable.style['transform'] = transform; |
- var topPercent = newScrollOffset / innerHeight * 100; |
- var heightPercent = outerHeight / innerHeight * 100; |
- this.vbar_.style.top = topPercent + '%'; |
- this.vbar_.style.height = heightPercent + '%'; |
+ double topPercent = newScrollOffset / innerHeight * 100.0; |
+ double heightPercent = outerHeight / innerHeight * 100.0; |
+ _vbar.style['top'] = '${topPercent}%'; |
+ _vbar.style['height'] = '${heightPercent}%'; |
} |
- scrollBy(scrollDelta) { |
- var oldScrollOffset = this.scrollOffset_; |
- this.scrollOffset += scrollDelta; |
- return this.scrollOffset_ != oldScrollOffset; |
+ bool scrollBy(double scrollDelta) { |
+ double oldScrollOffset = _scrollOffset; |
+ scrollOffset += scrollDelta; |
+ return _scrollOffset != oldScrollOffset; |
} |
- scheduleFlingUpdate_() { |
- this.flingAnimationId_ = requestAnimationFrame(this.updateFling_.bind(this)); |
+ void _scheduleFlingUpdate() { |
+ _flingAnimationId = window.requestAnimationFrame(_updateFling); |
} |
- stopFling_() { |
- cancelAnimationFrame(this.flingAnimationId_); |
- this.flingCurve_ = null; |
- this.flingAnimationId_ = null; |
- this.vbar_.style.opacity = 0; |
+ void _stopFling() { |
+ window.cancelAnimationFrame(_flingAnimationId); |
+ _flingCurve = null; |
+ _flingAnimationId = null; |
+ _vbar.style['opacity'] = '0'; |
} |
- updateFling_(timeStamp) { |
- var scrollDelta = this.flingCurve_.update(timeStamp); |
- if (!scrollDelta || !this.scrollBy(scrollDelta)) |
- return this.stopFling_(); |
- this.scheduleFlingUpdate_(); |
+ void _updateFling(double timeStamp) { |
+ double scrollDelta = _flingCurve.update(timeStamp); |
+ if (scrollDelta == 0.0 || !scrollBy(scrollDelta)) |
+ _stopFling(); |
+ else |
+ _scheduleFlingUpdate(); |
} |
- handleScrollStart_(event) { |
- this.vbar_.style.opacity = 1; |
+ void _handleScrollStart(_) { |
+ _vbar.style['opacity'] = '1'; |
} |
- handleScrollEnd_(event) { |
- this.vbar_.style.opacity = 0; |
+ void _handleScrollEnd(_) { |
+ _vbar.style['opacity'] = '0'; |
} |
- handleScrollUpdate_(event) { |
- this.scrollBy(-event.dy); |
+ void _handleScrollUpdate(GestureEvent event) { |
+ scrollBy(-event.dy); |
} |
- handleFlingStart_(event) { |
- this.flingCurve_ = new FlingCurve(-event.velocityY, event.timeStamp); |
- this.scheduleFlingUpdate_(); |
+ void _handleFlingStart(GestureEvent event) { |
+ _flingCurve = new FlingCurve(-event.velocityY, event.timeStamp); |
+ _scheduleFlingUpdate(); |
} |
- handleFlingCancel_(event) { |
- this.stopFling_(); |
+ void _handleFlingCancel(_) { |
+ _stopFling(); |
} |
- handleWheel_(event) { |
- this.scrollBy(-event.offsetY); |
+ void _handleWheel(WheelEvent event) { |
+ scrollBy(-event.offsetY); |
} |
-}.register(); |
+} |
+ |
+_init(script) => register(script, SkyScrollable); |
</script> |
</sky-element> |