@@ -29,15 +29,77 @@ class MusicPlayer extends StatefulWidget {
2929 _MusicPlayerState createState () => _MusicPlayerState ();
3030}
3131
32- class _MusicPlayerState extends State <MusicPlayer > {
33- final ValueNotifier <double > topPlayerOpacity = ValueNotifier (0.0 );
34- final ValueNotifier <double > middlePlayerOpacity = ValueNotifier (0.0 );
35- final ValueNotifier <double > bottomPlayerOpacity = ValueNotifier (1.0 );
36- final ValueNotifier <int > progress = ValueNotifier (0 );
32+ class _MusicPlayerState extends State <MusicPlayer >
33+ with SingleTickerProviderStateMixin {
34+ ValueNotifier <double > topPlayerOpacity;
35+ ValueNotifier <double > middlePlayerOpacity;
36+ ValueNotifier <double > bottomPlayerOpacity;
37+ ValueNotifier <int > progress;
38+ Animation <double > _xTween;
39+ Animation <double > _yTween;
40+ Animation <double > _radiusTween;
41+
42+ @override
43+ void initState () {
44+ topPlayerOpacity = ValueNotifier (0.0 );
45+ middlePlayerOpacity = ValueNotifier (0.0 );
46+ bottomPlayerOpacity = ValueNotifier (1.0 );
47+ progress = ValueNotifier (0 );
48+ GlobalParameters .radiusController = AnimationController (
49+ vsync: this ,
50+ duration: Duration (milliseconds: 800 ),
51+ );
52+ _xTween = Tween <double >(begin: 0.0 , end: 1.0 )
53+ .animate (GlobalParameters .radiusController);
54+ _radiusTween = Tween <double >(begin: 0.35 , end: 1.5 )
55+ .animate (GlobalParameters .radiusController);
56+ super .initState ();
57+ }
58+
59+ void initTween (
60+ {@required double halfOfHeight,
61+ @required double paddingTop,
62+ @required double firstSizedBox,
63+ @required double firstContainer,
64+ @required double secondSizedBox,
65+ @required double bigCircleRadius}) {
66+ if (_yTween == null ) {
67+ double begin = (- halfOfHeight +
68+ paddingTop +
69+ firstSizedBox +
70+ firstContainer +
71+ secondSizedBox +
72+ bigCircleRadius) /
73+ halfOfHeight;
74+ _yTween = Tween <double >(begin: begin, end: - 1.0 )
75+ .animate (GlobalParameters .radiusController);
76+ }
77+ }
78+
79+ @override
80+ void dispose () {
81+ GlobalParameters .radiusController.dispose ();
82+ super .dispose ();
83+ }
3784
3885 @override
3986 Widget build (BuildContext context) {
4087 Size size = MediaQuery .of (context).size;
88+ final double safeHeight = size.height -
89+ MediaQuery .of (context).padding.bottom -
90+ MediaQuery .of (context).padding.top;
91+ final double firstSizedBox = 10.0 ;
92+ final double firstContainer = 45.0 ;
93+ final double secondSizedBox = safeHeight * 0.05 ;
94+ final double bigCircleRadius = 107.0 ;
95+ initTween (
96+ halfOfHeight: size.height / 2 ,
97+ paddingTop: MediaQuery .of (context).padding.top,
98+ firstSizedBox: firstSizedBox,
99+ firstContainer: firstContainer,
100+ secondSizedBox: secondSizedBox,
101+ bigCircleRadius: bigCircleRadius,
102+ );
41103 return SnappingSheet (
42104 controller: GlobalParameters .snappingSheetController,
43105 initialSnappingPosition: SnappingPosition .pixels (
@@ -88,32 +150,42 @@ class _MusicPlayerState extends State<MusicPlayer> {
88150 return Stack (
89151 children: [
90152 FutureBuilder (
91- future:
92- GlobalParameters .currentSong.value.generateColors (),
93- builder: (context, snapshot) {
94- return Container (
95- width: double .infinity,
96- decoration: BoxDecoration (
97- color: Theme .of (context).scaffoldBackgroundColor,
98- gradient: LinearGradient (
99- colors: [
100- GlobalParameters
101- .currentSong.value.firstColor ??
153+ future:
154+ GlobalParameters .currentSong.value.generateColors (),
155+ builder: (context, snapshot) {
156+ return AnimatedBuilder (
157+ animation: _xTween,
158+ builder: (context, child) {
159+ return Container (
160+ width: double .infinity,
161+ decoration: BoxDecoration (
162+ color:
102163 Theme .of (context).scaffoldBackgroundColor,
103- GlobalParameters .currentSong.value.secondColor
104- ? .withOpacity (0 ) ??
105- Theme .of (context).scaffoldBackgroundColor,
106- ],
107- begin: Alignment .topRight,
108- end: Alignment .centerLeft,
109- ),
110- borderRadius: BorderRadius .only (
111- topLeft: Radius .circular (20 ),
112- topRight: Radius .circular (20 ),
113- ),
114- ),
115- );
116- }),
164+ gradient: RadialGradient (
165+ colors: [
166+ GlobalParameters
167+ .currentSong.value.firstColor ??
168+ Theme .of (context)
169+ .scaffoldBackgroundColor,
170+ GlobalParameters
171+ .currentSong.value.secondColor
172+ ? .withOpacity (0 ) ??
173+ Theme .of (context)
174+ .scaffoldBackgroundColor,
175+ ],
176+ center:
177+ Alignment (_xTween.value, _yTween.value),
178+ radius: _radiusTween.value,
179+ ),
180+ borderRadius: BorderRadius .only (
181+ topLeft: Radius .circular (20 ),
182+ topRight: Radius .circular (20 ),
183+ ),
184+ ),
185+ );
186+ });
187+ },
188+ ),
117189 SingleChildScrollView (
118190 physics: NeverScrollableScrollPhysics (),
119191 child: Column (
@@ -125,7 +197,13 @@ class _MusicPlayerState extends State<MusicPlayer> {
125197 visible: (percent == 0 ) ? false : true ,
126198 child: Opacity (
127199 opacity: percent,
128- child: TopMusicPlayer (),
200+ child: TopMusicPlayer (
201+ safeHeight: safeHeight,
202+ firstSizedBox: firstSizedBox,
203+ firstContainer: firstContainer,
204+ secondSizedBox: secondSizedBox,
205+ bigCircleRadius: bigCircleRadius,
206+ ),
129207 ),
130208 );
131209 },
0 commit comments