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

Side by Side Diff: sky/sdk/lib/widgets/popup_menu.dart

Issue 1241703003: Use AnimationVariables to drive PopupMenu animation (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: adjustedTime moar Created 5 years, 5 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/sdk/lib/animation/animation_performance.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 'dart:math' as math; 5 import 'dart:math' as math;
6 import 'dart:sky' as sky; 6 import 'dart:sky' as sky;
7 7
8 import 'package:sky/animation/animation_performance.dart'; 8 import 'package:sky/animation/animation_performance.dart';
9 import 'package:sky/painting/box_painter.dart'; 9 import 'package:sky/painting/box_painter.dart';
10 import 'package:sky/theme/colors.dart'; 10 import 'package:sky/theme/colors.dart';
(...skipping 28 matching lines...) Expand all
39 this.onStatusChanged, 39 this.onStatusChanged,
40 this.items, 40 this.items,
41 this.level 41 this.level
42 }) : super(key: key); 42 }) : super(key: key);
43 43
44 bool showing; 44 bool showing;
45 PopupMenuStatusChangedCallback onStatusChanged; 45 PopupMenuStatusChangedCallback onStatusChanged;
46 List<PopupMenuItem> items; 46 List<PopupMenuItem> items;
47 int level; 47 int level;
48 48
49 AnimatedType<double> _position; 49 AnimatedType<double> _opacity;
50 AnimatedType<double> _height;
51 AnimatedType<double> _width;
52 List<AnimatedType<double>> _itemOpacities;
50 AnimationPerformance _performance; 53 AnimationPerformance _performance;
51 54
52 void initState() { 55 void initState() {
53 _position = new AnimatedType<double>(0.0, end: 1.0);
54 _performance = new AnimationPerformance() 56 _performance = new AnimationPerformance()
55 ..variable = _position
56 ..addListener(_checkForStateChanged); 57 ..addListener(_checkForStateChanged);
58 _updateAnimationVariables();
57 watch(_performance); 59 watch(_performance);
58 _updateBoxPainter(); 60 _updateBoxPainter();
59 if (showing) 61 if (showing)
60 _open(); 62 _open();
61 } 63 }
62 64
63 void syncFields(PopupMenu source) { 65 void syncFields(PopupMenu source) {
64 if (showing != source.showing) { 66 if (showing != source.showing) {
65 showing = source.showing; 67 showing = source.showing;
66 if (showing) 68 if (showing)
67 _open(); 69 _open();
68 else 70 else
69 _close(); 71 _close();
70 } 72 }
71 onStatusChanged = source.onStatusChanged; 73 onStatusChanged = source.onStatusChanged;
72 if (level != source.level) { 74 if (level != source.level) {
73 level = source.level; 75 level = source.level;
74 _updateBoxPainter(); 76 _updateBoxPainter();
75 } 77 }
78 if (items.length != source.items.length)
79 _updateAnimationVariables();
76 items = source.items; 80 items = source.items;
77 super.syncFields(source); 81 super.syncFields(source);
78 } 82 }
79 83
84 void _updateAnimationVariables() {
85 _opacity = new AnimatedType<double>(0.0, end: 1.0);
86 _width = new AnimatedType<double>(0.5, end: 1.0, interval: new Interval(0.0, 0.5));
87 _height = new AnimatedType<double>(0.0, end: 1.0, interval: new Interval(0.0 , 0.33));
88 _itemOpacities = new List<AnimatedType<double>>();
89 double unit = 1.0 / items.length;
90 for (int i = 0; i < items.length; ++i) {
91 double start = i * unit;
92 double end = (start + 1.5 * unit).clamp(0.0, 1.0);
93 _itemOpacities.add(new AnimatedType<double>(
94 0.0, end: 1.0, interval: new Interval(start, end)));
95 }
96 List<AnimatedVariable> variables = new List<AnimatedVariable>()
97 ..add(_opacity)
98 ..add(_width)
99 ..add(_height)
100 ..addAll(_itemOpacities);
101 _performance.variable = new AnimatedList(variables);
102 }
103
80 void _updateBoxPainter() { 104 void _updateBoxPainter() {
81 _painter = new BoxPainter(new BoxDecoration( 105 _painter = new BoxPainter(new BoxDecoration(
82 backgroundColor: Grey[50], 106 backgroundColor: Grey[50],
83 borderRadius: 2.0, 107 borderRadius: 2.0,
84 boxShadow: shadows[level])); 108 boxShadow: shadows[level]));
85 } 109 }
86 110
87 PopupMenuStatus get _status => _position.value != 0.0 ? PopupMenuStatus.active : PopupMenuStatus.inactive; 111 PopupMenuStatus get _status => _opacity.value != 0.0 ? PopupMenuStatus.active : PopupMenuStatus.inactive;
88 112
89 PopupMenuStatus _lastStatus; 113 PopupMenuStatus _lastStatus;
90 void _checkForStateChanged() { 114 void _checkForStateChanged() {
91 PopupMenuStatus status = _status; 115 PopupMenuStatus status = _status;
92 if (_lastStatus != null && status != _lastStatus && onStatusChanged != null) 116 if (_lastStatus != null && status != _lastStatus && onStatusChanged != null)
93 onStatusChanged(status); 117 onStatusChanged(status);
94 _lastStatus = status; 118 _lastStatus = status;
95 } 119 }
96 120
97 void _open() { 121 void _open() {
98 _performance 122 _performance
99 ..duration = _kMenuOpenDuration 123 ..duration = _kMenuOpenDuration
100 ..play(); 124 ..play();
101 } 125 }
102 126
103 void _close() { 127 void _close() {
104 _performance 128 _performance
105 ..duration = _kMenuCloseDuration 129 ..duration = _kMenuCloseDuration
106 ..reverse(); 130 ..reverse();
107 } 131 }
108 132
109 BoxPainter _painter; 133 BoxPainter _painter;
110 134
111 double _opacityFor(int i) {
112 assert(_position.value != null);
113 if (_position.value == null || _position.value == 1.0)
114 return 1.0;
115 double unit = 1.0 / items.length;
116 double duration = 1.5 * unit;
117 double start = i * unit;
118 return math.max(0.0, math.min(1.0, (_position.value - start) / duration));
119 }
120
121 Widget build() { 135 Widget build() {
122 int i = 0; 136 int i = 0;
123 List<Widget> children = new List.from(items.map((Widget item) { 137 List<Widget> children = new List.from(items.map((Widget item) {
124 return new Opacity(opacity: _opacityFor(i++), child: item); 138 return new Opacity(opacity: _itemOpacities[i++].value, child: item);
125 })); 139 }));
126 140
127 return new Opacity( 141 return new Opacity(
128 opacity: math.min(1.0, _position.value * 3.0), 142 opacity: math.min(1.0, _opacity.value * 3.0),
129 child: new Container( 143 child: new Container(
130 margin: new EdgeDims.all(_kMenuMargin), 144 margin: new EdgeDims.all(_kMenuMargin),
131 child: new CustomPaint( 145 child: new CustomPaint(
132 callback: (sky.Canvas canvas, Size size) { 146 callback: (sky.Canvas canvas, Size size) {
133 double width = math.min(size.width, size.width * (0.5 + _position.va lue * 2.0)); 147 double width = _width.value * size.width;
134 double height = math.min(size.height, size.height * _position.value * 1.5); 148 double height = _height.value * size.height;
135 _painter.paint(canvas, new Rect.fromLTRB(size.width - width, 0.0, wi dth, height)); 149 _painter.paint(canvas, new Rect.fromLTRB(size.width - width, 0.0, wi dth, height));
136 }, 150 },
137 child: new ConstrainedBox( 151 child: new ConstrainedBox(
138 constraints: new BoxConstraints( 152 constraints: new BoxConstraints(
139 minWidth: _kMenuMinWidth, 153 minWidth: _kMenuMinWidth,
140 maxWidth: _kMenuMaxWidth 154 maxWidth: _kMenuMaxWidth
141 ), 155 ),
142 child: new ShrinkWrapWidth( 156 child: new ShrinkWrapWidth(
143 stepWidth: _kMenuWidthStep, 157 stepWidth: _kMenuWidthStep,
144 child: new ScrollableViewport( 158 child: new ScrollableViewport(
145 child: new Container( 159 child: new Container(
146 padding: const EdgeDims.symmetric( 160 padding: const EdgeDims.symmetric(
147 horizontal: _kMenuHorizontalPadding, 161 horizontal: _kMenuHorizontalPadding,
148 vertical: _kMenuVerticalPadding 162 vertical: _kMenuVerticalPadding
149 ), 163 ),
150 child: new Block(children) 164 child: new Block(children)
151 ) 165 )
152 ) 166 )
153 ) 167 )
154 ) 168 )
155 ) 169 )
156 ) 170 )
157 ); 171 );
158 } 172 }
159 173
160 } 174 }
OLDNEW
« no previous file with comments | « sky/sdk/lib/animation/animation_performance.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698