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

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

Issue 942413002: Port sky-drawer to Dart (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: 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/animation/timer.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="animation/controller.sky" as="AnimationController" /> 6 <import src="sky-element.sky" />
7 <import src="animation/curves.sky" as="Curves" />
8 <import src="sky-element/sky-element.sky" as="SkyElement" />
9 <import src="sky-scrollable.sky" /> 7 <import src="sky-scrollable.sky" />
10 8
11 <sky-element 9 <sky-element>
12 name="sky-drawer"
13 on-pointerdown="handlePointerDown"
14 on-pointermove="handlePointerMove"
15 on-pointerup="handlePointerUp"
16 on-pointercancel="handlePointerCancel">
17 <template> 10 <template>
18 <style> 11 <style>
19 #mask { 12 #mask {
20 background-color: black; 13 background-color: black;
21 will-change: opacity; 14 will-change: opacity;
22 position: absolute; 15 position: absolute;
23 top: 0; 16 top: 0;
24 left: 0; 17 left: 0;
25 bottom: 0; 18 bottom: 0;
26 right: 0; 19 right: 0;
27 } 20 }
28 #content { 21 #content {
29 background-color: yellow; 22 background-color: yellow;
30 will-change: transform; 23 will-change: transform;
31 position: absolute; 24 position: absolute;
32 width: 256px; 25 width: 256px;
33 top: 0; 26 top: 0;
34 left: 0; 27 left: 0;
35 bottom: 0; 28 bottom: 0;
36 } 29 }
37 </style> 30 </style>
38 <div id="mask" on-click="handleMaskClick" /> 31 <div id="mask" />
39 <div id="content" on-gestureflingstart="handleFlingStart"> 32 <div id="content">
40 <content/> 33 <content/>
41 </div> 34 </div>
42 </template> 35 </template>
43 <script> 36 <script>
44 const kWidth = 256; 37 import "animation/controller.dart";
45 const kMinFlingVelocity = 0.4; 38 import "animation/curves.dart";
46 const kMinAnimationDurationMS = 246; 39 import "animation/timer.dart";
47 const kMaxAnimationDurationMS = 600; 40 import "dart:math" as math;
48 const kAnimationCurve = Curves.easeInOut; 41 import "dart:sky";
49 42
50 module.exports = class extends SkyElement { 43 const double _kWidth = 256.0;
51 created() { 44 const double _kMinFlingVelocity = 0.4;
52 this.position_ = 0; 45 const double _kMinAnimationDurationMS = 246.0;
53 this.mask_ = null; 46 const double _kMaxAnimationDurationMS = 600.0;
54 this.content_ = null; 47 const Cubic _kAnimationCurve = easeOut;
55 this.animation_ = new AnimationController(this); 48
49 @Tagname('sky-drawer')
50 class SkyDrawer extends SkyElement implements AnimationDelegate {
51 Element _mask;
52 Element _content;
53 double _position = 0.0;
54 AnimationController _animation;
55
56 SkyDrawer() {
57 _animation = new AnimationController(this);
58
59 addEventListener('pointerdown', _handlePointerDown);
60 addEventListener('pointermove', _handlePointerMove);
61 addEventListener('pointerup', _handlePointerUp);
62 addEventListener('pointercancel', _handlePointerCancel);
56 } 63 }
57 64
58 shadowRootReady() { 65 void shadowRootReady() {
59 this.mask_ = this.shadowRoot.getElementById('mask'); 66 _mask = shadowRoot.getElementById('mask');
60 this.content_ = this.shadowRoot.getElementById('content'); 67 _mask.addEventListener('click', _handleMaskClick);
61 this.position = -kWidth; 68 _content = shadowRoot.getElementById('content');
69 _content.addEventListener('gestureflingstart', _handleFlingStart);
70 position = -_kWidth;
62 } 71 }
63 72
64 toggle() { 73 void toggle() {
65 if (this.isMostlyClosed) 74 if (isMostlyClosed)
66 this.open(); 75 open();
67 else 76 else
68 this.close(); 77 close();
69 } 78 }
70 79
71 open() { 80 void open() {
72 this.animateToPosition_(0); 81 _animateToPosition(0.0);
73 } 82 }
74 83
75 close() { 84 void close() {
76 this.animateToPosition_(-kWidth); 85 _animateToPosition(-_kWidth);
77 } 86 }
78 87
79 get isClosed() { 88 bool get isClosed => _position <= -_kWidth;
80 return this.position_ <= -kWidth; 89 bool get isMostlyClosed => _position <= -_kWidth / 2;
90 double get position => _position;
91
92 set position(double value) {
93 double newPosition = math.min(0.0, math.max(value, -_kWidth));
94 _position = newPosition;
95 _content.style['transform'] = 'translateX(${newPosition}px)';
96 _mask.style['opacity'] = '${(newPosition / _kWidth + 1) * 0.25}';
97 style['display'] = isClosed ? 'none' : '';
81 } 98 }
82 99
83 get isMostlyClosed() { 100 void _settle() {
84 return this.position_ <= -kWidth / 2; 101 if (isMostlyClosed)
102 close();
103 else
104 open();
85 } 105 }
86 106
87 get position() { 107 void _animateToPosition(double targetPosition) {
88 return this.position_; 108 double currentPosition = _position;
109 double distance = (targetPosition - currentPosition).abs();
110 double duration = _kMaxAnimationDurationMS * distance / _kWidth;
111 _animation.start(
112 begin: currentPosition,
113 end: targetPosition,
114 duration: math.max(_kMinAnimationDurationMS, duration),
115 curve: _kAnimationCurve);
89 } 116 }
90 117
91 set position(value) { 118 void updateAnimation(double p) {
92 var newPosition = Math.min(0, Math.max(value, -kWidth)); 119 position = p;
93 this.position_ = newPosition;
94 this.content_.style.transform = 'translateX(' + newPosition + 'px)';
95 this.mask_.style.opacity = (newPosition / kWidth + 1) * 0.25;
96 this.style.display = this.isClosed ? 'none' : '';
97 } 120 }
98 121
99 settle_() { 122 void _handleMaskClick(_) {
100 if (this.isMostlyClosed) 123 close();
101 this.close();
102 else
103 this.open();
104 } 124 }
105 125
106 animateToPosition_(targetPosition) { 126 void _handlePointerDown(_) {
107 var currentPosition = this.position_; 127 _animation.stop();
108 var distance = Math.abs(targetPosition - currentPosition);
109 var duration = kMaxAnimationDurationMS * distance / kWidth;
110 this.animation_.start({
111 begin: currentPosition,
112 end: targetPosition,
113 duration: Math.max(kMinAnimationDurationMS, duration),
114 curve: kAnimationCurve,
115 });
116 } 128 }
117 129
118 updateAnimation(position) { 130 void _handlePointerMove(PointerEvent event) {
119 this.position = position; 131 position += event.dx;
120 } 132 }
121 133
122 handleMaskClick() { 134 void _handlePointerUp(_) {
123 this.close(); 135 if (!_animation.isAnimating)
136 _settle();
124 } 137 }
125 138
126 handlePointerDown(event) { 139 void _handlePointerCancel(_) {
127 this.animation_.stop(); 140 if (!_animation.isAnimating)
141 _settle();
128 } 142 }
129 143
130 handlePointerMove(event) { 144 void _handleFlingStart(event) {
131 this.position += event.dx; 145 double direction = event.velocityX.sign();
132 } 146 double velocityX = event.velocityX.abs() / 1000;
133 147 if (velocityX < _kMinFlingVelocity)
134 handlePointerUp(event) {
135 if (!this.animation_.isAnimating)
136 this.settle_();
137 }
138
139 handlePointerCancel(event) {
140 if (!this.animation_.isAnimating)
141 this.settle_();
142 }
143
144 handleFlingStart(event) {
145 var direction = Math.sign(event.velocityX);
146 var velocityX = Math.abs(event.velocityX) / 1000;
147 if (velocityX < kMinFlingVelocity)
148 return; 148 return;
149 var targetPosition = direction < 0 ? -kWidth : 0; 149 double targetPosition = direction < 0.0 ? -kWidth : 0.0;
150 var currentPosition = this.position_; 150 double currentPosition = _position;
151 var distance = Math.abs(targetPosition - currentPosition); 151 double distance = (targetPosition - currentPosition).abs();
152 var duration = distance / velocityX; 152 double duration = distance / velocityX;
153 this.animation_.start({ 153 _animation.start(
154 begin: currentPosition, 154 begin: currentPosition,
155 end: targetPosition, 155 end: targetPosition,
156 duration: duration, 156 duration: duration,
157 curve: Curves.linear, 157 curve: linear);
158 });
159 } 158 }
160 }.register(); 159 }
160
161 _init(script) => register(script, SkyDrawer);
161 </script> 162 </script>
162 </sky-element> 163 </sky-element>
OLDNEW
« no previous file with comments | « sky/framework/animation/timer.sky ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698