-
Notifications
You must be signed in to change notification settings - Fork 225
/
ShapeBorderClipper .dart
137 lines (125 loc) · 4.16 KB
/
ShapeBorderClipper .dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new UserOptions(),
);
}
}
class UserOptions extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new UserOptionsState();
}
}
class UserOptionsState extends State<UserOptions>
with SingleTickerProviderStateMixin {
AnimationController _controller;
static const _PANEL_HEADER_HEIGHT = 32.0;
static const double _kFrontHeadingHeight = 32.0;
@override
void initState() {
super.initState();
_controller = new AnimationController(
duration: const Duration(milliseconds: 100), value: 1.0, vsync: this);
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
bool get _isPanelVisible {
final AnimationStatus status = _controller.status;
return status == AnimationStatus.completed ||
status == AnimationStatus.forward;
}
Animation<RelativeRect> _getPanelAnimation(BoxConstraints constraints) {
final double height = constraints.biggest.height;
final double top = height / 3;
final double bottom = -_PANEL_HEADER_HEIGHT;
return new RelativeRectTween(
begin: new RelativeRect.fromLTRB(0.0, top, 0.0, bottom),
end: new RelativeRect.fromLTRB(0.0, 0.0, 0.0, 0.0),
).animate(new CurvedAnimation(parent: _controller, curve: Curves.linear));
}
final Tween<BorderRadius> _kFrontHeadingBevelRadius = new BorderRadiusTween(
begin: const BorderRadius.only(
topLeft: Radius.circular(22.0),
topRight: Radius.circular(22.0),
),
end: const BorderRadius.only(
topLeft: Radius.circular(_kFrontHeadingHeight),
topRight: Radius.circular(_kFrontHeadingHeight),
),
);
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
elevation: 0.0,
title: new Text('Shape Border Clipper'),
leading: new IconButton(
icon: new AnimatedIcon(
icon: AnimatedIcons.close_menu,
progress: _controller.view,
),
onPressed: () {
_controller.fling(velocity: _isPanelVisible ? -1.0 : 1.0);
},
),
),
body: new LayoutBuilder(
builder: _buildStack,
),
);
}
Widget _buildStack(BuildContext context, BoxConstraints constraints) {
final ThemeData theme = Theme.of(context);
return new Container(
color: theme.primaryColor,
child: new Stack(
children: <Widget>[
new PositionedTransition(
rect: _getPanelAnimation(constraints),
child: new AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
return new PhysicalShape(
elevation: 12.0,
color: Theme.of(context).canvasColor,
clipper: new ShapeBorderClipper(
shape: new BeveledRectangleBorder(
borderRadius:
_kFrontHeadingBevelRadius.lerp(_controller.value),
)),
child: new Material(
borderRadius: const BorderRadius.only(
topLeft: const Radius.circular(16.0),
topRight: const Radius.circular(16.0)),
elevation: 12.0,
child: new Column(
children: <Widget>[
new Container(
height: _PANEL_HEADER_HEIGHT,
child: new Center(
child: new Text('Aseem'),
),
),
new Expanded(
child: new Center(child: new Text("Wangoo")))
],
),
),
);
},
),
)
],
),
);
}
}