Skip to content

Commit 8031e1d

Browse files
committed
added animation to gradient for TopMusicPlayer
1 parent c822fe0 commit 8031e1d

File tree

9 files changed

+271
-81
lines changed

9 files changed

+271
-81
lines changed

android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ android {
3333
minSdkVersion 16
3434
targetSdkVersion 30
3535
versionCode flutterVersionCode.toInteger()
36-
versionName "0.0.12"
36+
versionName "0.0.13"
3737
}
3838

3939
buildTypes {

lib/constants.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ abstract class ConstantColors {
1313
static const Color disabledColor = Color(0xFFC5C5C5);
1414
static const Color splashColor = Color(0xFF7F2BCF);
1515
static const Color highlightColor = Color(0xFFB538A7);
16+
// TODO: try this colors
17+
// Color(0xFFF13AD3),
18+
// Color(0xFF63BAC4),
1619
static const Color errorColor = Color(0xFFB53850);
1720
}
1821

lib/global/global_parameters.dart

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ abstract class GlobalParameters {
2929
static AnimationController playAnimationController;
3030
static AnimationController waveController;
3131
static AnimationController circleController;
32-
static PageController musicPageController = PageController();
32+
static AnimationController radiusController;
3333
static final ValueNotifier<bool> playNotifier = ValueNotifier(false);
3434
static final ValueNotifier<Song> currentSong = ValueNotifier(songs[0]);
3535
static int songNumber = 0;
@@ -42,10 +42,12 @@ abstract class GlobalParameters {
4242
playNotifier.value = false;
4343
playAnimationController.reverse();
4444
waveController.reverse();
45+
radiusController.reverse();
4546
} else {
4647
playNotifier.value = true;
4748
playAnimationController.forward();
4849
waveController.forward();
50+
radiusController.forward();
4951
}
5052
}
5153

@@ -65,32 +67,36 @@ abstract class GlobalParameters {
6567
songSeconds.value = 0;
6668
}
6769

70+
static void moveToPreviousIndex() {
71+
if (songNumber != 0) {
72+
songNumber--;
73+
} else {
74+
songNumber = songs.length - 1;
75+
}
76+
}
77+
6878
static void previousSong() async {
6979
if (songs.length > 0) {
70-
int index = songs.indexOf(currentSong.value);
71-
if (index != 0) {
72-
index--;
73-
} else {
74-
index = songs.length - 1;
75-
}
76-
Song song = songs[index];
77-
songNumber = index;
80+
moveToPreviousIndex();
81+
Song song = songs[songNumber];
7882
await song.generateColors();
7983
currentSong.value = song;
8084
songSeconds.value = 0;
8185
}
8286
}
8387

88+
static void moveToNextIndex() {
89+
if (songNumber != songs.length - 1) {
90+
songNumber++;
91+
} else {
92+
songNumber = 0;
93+
}
94+
}
95+
8496
static void nextSong() async {
8597
if (songs.length > 0) {
86-
int index = songs.indexOf(currentSong.value);
87-
if (index != songs.length - 1) {
88-
index++;
89-
} else {
90-
index = 0;
91-
}
92-
Song song = songs[index];
93-
songNumber = index;
98+
moveToNextIndex();
99+
Song song = songs[songNumber];
94100
await song.generateColors();
95101
currentSong.value = song;
96102
songSeconds.value = 0;

lib/models/song.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Song {
3434
Color primaryColor;
3535
Color firstColor;
3636
Color secondColor;
37+
final randomInstance = Random();
3738

3839
Future<void> generateColors() async {
3940
if(albumImageUrl.isEmpty) {
@@ -101,8 +102,8 @@ class Song {
101102
List.generate(
102103
3,
103104
(index) => PaletteColor(
104-
Color((Random().nextDouble() * 0xFFFFFF).toInt()),
105-
Random().nextInt(10000),
105+
Color((randomInstance.nextDouble() * 0xFFFFFF).toInt()),
106+
randomInstance.nextInt(10000),
106107
),
107108
),
108109
);

lib/widgets/middle_music_player.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
part of 'music_player.dart';
22

3-
class MiddleMusicPlayer extends StatelessWidget {
3+
class MiddleMusicPlayer extends StatefulWidget {
44
MiddleMusicPlayer({
55
Key key,
66
}) : super(key: key);
77

8+
@override
9+
State<MiddleMusicPlayer> createState() => _MiddleMusicPlayerState();
10+
}
11+
12+
class _MiddleMusicPlayerState extends State<MiddleMusicPlayer> {
813
@override
914
Widget build(BuildContext context) {
1015
Size size = MediaQuery.of(context).size;

lib/widgets/music_player.dart

Lines changed: 109 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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
},

lib/widgets/player_controls.dart

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
part of 'music_player.dart';
22

33
class PlayerControls extends StatelessWidget {
4-
const PlayerControls({
4+
PlayerControls({
55
Key key,
6-
}) : super(key: key);
6+
this.pageController,
7+
});
8+
9+
final PageController pageController;
10+
final Duration duration = Duration(milliseconds: 400);
11+
final Curve curve = Curves.easeInOut;
712

813
@override
914
Widget build(BuildContext context) {
@@ -15,7 +20,12 @@ class PlayerControls extends StatelessWidget {
1520
color: Theme.of(context).focusColor,
1621
iconSize: 60,
1722
onPressed: () {
18-
GlobalParameters.previousSong();
23+
if(pageController!=null){
24+
GlobalParameters.moveToPreviousIndex();
25+
pageController.animateToPage(GlobalParameters.songNumber, duration: duration, curve: curve);
26+
}else {
27+
GlobalParameters.previousSong();
28+
}
1929
},
2030
),
2131
ValueListenableBuilder(
@@ -38,7 +48,12 @@ class PlayerControls extends StatelessWidget {
3848
color: Theme.of(context).focusColor,
3949
iconSize: 60,
4050
onPressed: () {
41-
GlobalParameters.nextSong();
51+
if(pageController!=null){
52+
GlobalParameters.moveToNextIndex();
53+
pageController.animateToPage(GlobalParameters.songNumber, duration: duration, curve: curve);
54+
}else {
55+
GlobalParameters.nextSong();
56+
}
4257
},
4358
),
4459
],

0 commit comments

Comments
 (0)