Index: sky/framework/sky-drawer.sky |
diff --git a/sky/framework/sky-drawer.sky b/sky/framework/sky-drawer.sky |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7512bfe2e8d4566da76b394d99ee1023e1a2871f |
--- /dev/null |
+++ b/sky/framework/sky-drawer.sky |
@@ -0,0 +1,156 @@ |
+<!-- |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+--> |
+<import src="animation/controller.sky" as="AnimationController" /> |
+<import src="animation/curves.sky" as="Curves" /> |
+<import src="sky-element/sky-element.sky" as="SkyElement" /> |
+<import src="sky-scrollable.sky" /> |
+ |
+<sky-element |
+ name="sky-drawer" |
+ on-pointerdown="handlePointerDown" |
+ on-pointermove="handlePointerMove" |
+ on-pointerup="handlePointerUp" |
+ on-pointercancel="handlePointerCancel"> |
+<template> |
+ <style> |
+ :host { |
+ position: absolute; |
esprehn
2015/01/29 19:03:57
This is fine for now, but I sort of feel like the
abarth-chromium
2015/01/29 19:16:45
Ok. I'll move this into the scaffold.
|
+ top: 0; |
+ left: 0; |
+ bottom: 0; |
+ right: 0; |
+ } |
+ #mask { |
+ background-color: black; |
+ will-change: opacity; |
+ position: absolute; |
+ top: 0; |
+ left: 0; |
+ bottom: 0; |
+ right: 0; |
+ } |
+ #overlay { |
esprehn
2015/01/29 19:03:57
Is the overlay the glass effect?
abarth-chromium
2015/01/29 19:16:45
I should probably rename it to "content". It's th
|
+ background-color: yellow; |
+ will-change: transform; |
+ position: absolute; |
+ width: 256px; |
+ top: 0; |
+ left: 0; |
+ bottom: 0; |
+ } |
+ </style> |
+ <div id="mask" on-click="handleMaskClick" /> |
+ <div id="overlay"> |
+ <content/> |
+ </div> |
+</template> |
+<script> |
+const kWidth = 256; |
+const kMinAnimationDurationMS = 120; |
+const kMaxAnimationDurationMS = 500; |
+const kAnimationCurve = Curves.easeInOut; |
+ |
+module.exports = class extends SkyElement { |
+ created() { |
+ this.previousX_ = 0; |
+ this.position_ = 0; |
+ this.mask_ = null; |
+ this.overlay_ = null; |
+ this.animation_ = new AnimationController(this); |
esprehn
2015/01/29 19:03:57
This way to having the delegate only works when wi
abarth-chromium
2015/01/29 19:16:45
Yeah.
|
+ } |
+ |
+ shadowRootReady() { |
+ this.mask_ = this.shadowRoot.getElementById('mask'); |
+ this.overlay_ = this.shadowRoot.getElementById('overlay'); |
+ this.position = -kWidth; |
+ } |
+ |
+ toggle() { |
+ if (this.isMostlyClosed) |
+ this.open(); |
+ else |
+ this.close(); |
+ } |
+ |
+ open() { |
+ this.animateToPosition_(0); |
+ } |
+ |
+ close() { |
+ this.animateToPosition_(-kWidth); |
+ } |
+ |
+ get isClosed() { |
+ return this.position_ <= -kWidth; |
+ } |
+ |
+ get isMostlyClosed() { |
+ return this.position_ <= -kWidth / 2; |
+ } |
+ |
+ get position() { |
+ return this.position_; |
+ } |
+ |
+ set position(value) { |
+ var newPosition = Math.min(0, Math.max(value, -kWidth)); |
+ this.position_ = newPosition; |
+ this.overlay_.style.transform = 'translateX(' + newPosition + 'px)'; |
+ this.mask_.style.opacity = (newPosition / kWidth + 1) * 0.25; |
+ this.style.display = this.isClosed ? 'none' : ''; |
+ } |
+ |
+ settle_() { |
+ if (this.isMostlyClosed) |
+ this.close(); |
+ else |
+ this.open(); |
+ } |
+ |
+ animateToPosition_(targetPosition) { |
+ var currentPosition = this.position_; |
+ var animationDistance = Math.abs(targetPosition - currentPosition); |
+ var duration = kMaxAnimationDurationMS * animationDistance / kWidth; |
+ this.animation_.start({ |
+ begin: currentPosition, |
+ end: targetPosition, |
+ duration: Math.max(kMinAnimationDurationMS, duration), |
+ curve: kAnimationCurve, |
+ }); |
+ } |
+ |
+ updateAnimation(position) { |
+ this.position = position; |
+ } |
+ |
+ handleMaskClick() { |
+ this.close(); |
+ } |
+ |
+ handlePointerDown(event) { |
+ this.animation_.stop(); |
+ this.previousX_ = event.x; |
+ } |
+ |
+ handlePointerMove(event) { |
+ // TODO(abarth): Implement event.dx; |
+ var deltaX = event.x - this.previousX_; |
+ this.previousX_ = event.x; |
+ this.position += deltaX; |
+ } |
+ |
+ handlePointerUp(event) { |
+ if (!this.animation_.isAnimating) |
+ this.settle_(); |
+ } |
+ |
+ handlePointerCancel(event) { |
+ if (!this.animation_.isAnimating) |
+ this.settle_(); |
+ } |
+}.register(); |
+</script> |
+</sky-element> |