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

Side by Side Diff: sky/framework/components/popup_menu.dart

Issue 1017193004: Improve the openning animation for PopupMenu (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 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/examples/stocks-fn/lib/stock_menu.dart ('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 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 import '../animation/animated_value.dart'; 5 import '../animation/animated_value.dart';
6 import '../fn.dart'; 6 import '../fn.dart';
7 import '../theme/colors.dart'; 7 import '../theme/colors.dart';
8 import '../theme/view-configuration.dart';
9 import 'dart:math' as math;
10 import 'dart:sky' as sky;
8 import 'material.dart'; 11 import 'material.dart';
9 import 'popup_menu_item.dart'; 12 import 'popup_menu_item.dart';
10 13
11 const double _kItemInitialOpacity = 0.0; 14 const double _kItemFadeDuration = 300.0;
12 const double _kItemFinalOpacity = 1.0; 15 const double _kItemFadeDelay = 100.0;
13 const double _kItemFadeDuration = 500.0; 16 const double _kMenuExpandDuration = 300.0;
14 const double _kItemFadeDelay = 200.0; 17
18 class PopupMenuController {
19 bool isOpen = false;
20 AnimatedValue position = new AnimatedValue(0.0);
21
22 void open() {
23 isOpen = true;
24 position.animateTo(1.0, _kMenuExpandDuration);
25 }
26
27 void close() {
28 position.animateTo(0.0, _kMenuExpandDuration);
29 // TODO(abarth): We shouldn't mark the menu as closed until the animation
30 // completes.
31 isOpen = false;
32 }
33 }
15 34
16 class PopupMenu extends Component { 35 class PopupMenu extends Component {
17 static final Style _style = new Style(''' 36 static final Style _style = new Style('''
18 border-radius: 2px; 37 border-radius: 2px;
19 padding: 8px 0; 38 padding: 8px 0;
39 box-sizing: border-box;
20 background-color: ${Grey[50]};''' 40 background-color: ${Grey[50]};'''
21 ); 41 );
22 42
23 List<List<Node>> items; 43 List<List<Node>> items;
24 int level; 44 int level;
45 PopupMenuController controller;
46
47 AnimatedValueListener _position;
25 List<AnimatedValue> _opacities; 48 List<AnimatedValue> _opacities;
49 int _width;
50 int _height;
26 51
27 PopupMenu({ Object key, this.items, this.level }) : super(key: key) { 52 PopupMenu({ Object key, this.controller, this.items, this.level })
28 _opacities = new List.from(items.map( 53 : super(key: key) {
29 (item) => new AnimatedValue(_kItemInitialOpacity))); 54 _position = new AnimatedValueListener(this, controller.position);
30 } 55 }
31 56
32 // TODO(abarth): Rather than using didMount, we should have the parent 57 void _ensureItemAnimations() {
33 // component kick off these animations. 58 if (_opacities != null && controller.isOpen)
34 void didMount() { 59 return;
60 _opacities = new List.from(items.map((_) => new AnimatedValue(0.0)));
35 int i = 0; 61 int i = 0;
36 _opacities.forEach((opacity) { 62 _opacities.forEach((opacity) {
37 opacity.animateTo(_kItemFinalOpacity, _kItemFadeDuration, 63 opacity.animateTo(1.0, _kItemFadeDuration,
38 initialDelay: _kItemFadeDelay * i++); 64 initialDelay: _kItemFadeDelay * ++i);
39 }); 65 });
40 } 66 }
41 67
68 String _inlineStyle() {
69 double value = _position.value;
70 if (value == null || value == 1.0 || _height == null || _width == null)
71 return null;
72 return '''
73 opacity: ${math.min(1.0, value * 1.5)};
74 width: ${math.min(_width, _width * value * 3.0)}px;
75 height: ${_height * value}px;''';
76 }
77
78 void didMount() {
79 setState(() {
80 var root = getRoot();
81 _width = root.clientWidth;
82 _height = root.clientHeight;
83 });
84 }
85
86 void didUnmount() {
87 _position.stopListening();
88 }
89
42 Node build() { 90 Node build() {
91 _position.ensureListening();
92 _ensureItemAnimations();
93
43 List<Node> children = []; 94 List<Node> children = [];
44 int i = 0; 95
45 items.forEach((List<Node> item) { 96 if (controller.isOpen) {
46 children.add( 97 int i = 0;
47 new PopupMenuItem(key: i, children: item, opacity: _opacities[i])); 98 items.forEach((List<Node> item) {
48 ++i; 99 children.add(
49 }); 100 new PopupMenuItem(key: i, children: item, opacity: _opacities[i]));
101 ++i;
102 });
103 }
50 104
51 return new Material( 105 return new Material(
52 style: _style, 106 style: _style,
107 inlineStyle: _inlineStyle(),
53 children: children, 108 children: children,
54 level: level 109 level: level
55 ); 110 );
56 } 111 }
57 } 112 }
OLDNEW
« no previous file with comments | « sky/examples/stocks-fn/lib/stock_menu.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698