Chromium Code Reviews| 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> |