1
1
import 'package:flutter/material.dart' ;
2
- import 'dart:async' ;
3
2
import 'dart:math' ;
4
3
5
4
class FlipLoader extends StatefulWidget {
5
+ Color loaderBackground;
6
+ Color iconColor;
7
+ IconData icon;
8
+ String animationType;
9
+
10
+ FlipLoader ({this .loaderBackground = Colors .redAccent, this .iconColor = Colors .white, this .icon = Icons .sync , this .animationType = "full_flip" });
11
+
12
+
6
13
@override
7
- _FlipLoaderState createState () => _FlipLoaderState ();
14
+ _FlipLoaderState createState () => _FlipLoaderState (this .loaderBackground, this .iconColor, this .icon, this .animationType );
8
15
}
9
16
10
17
class _FlipLoaderState extends State <FlipLoader >
11
18
with SingleTickerProviderStateMixin {
19
+
12
20
AnimationController controller;
13
21
Animation <double > rotationHorizontal;
14
22
Animation <double > rotationVertical;
15
- double verticalRotation = 0.0 ;
16
- double horizontalRotation = 0.0 ;
23
+ Color loaderColor;
24
+ Color iconColor;
25
+ IconData icon;
26
+ Widget loaderIconChild;
27
+ String animationType;
28
+
29
+ _FlipLoaderState (this .loaderColor, this .iconColor, this .icon, this .animationType);
17
30
18
31
@override
19
32
void initState () {
20
33
super .initState ();
21
34
22
- controller = AnimationController (
23
- duration: const Duration (milliseconds: 4000 ), vsync: this );
24
- rotationHorizontal = Tween <double >(begin: - 1.0 , end: 1.0 ).animate (
25
- CurvedAnimation (
26
- parent: controller,
27
- curve: Interval (0.0 , 0.50 , curve: Curves .linear)));
28
- rotationVertical = Tween <double >(begin: - 1.0 , end: 1.0 ).animate (
29
- CurvedAnimation (
30
- parent: controller,
31
- curve: Interval (0.50 , 1.0 , curve: Curves .linear)));
32
-
35
+ controller = createAnimationController (animationType);
33
36
34
37
controller.addStatusListener ((status){
35
- if (status == AnimationStatus .completed) {
36
- setState (() {
37
- controller.repeat ();
38
- });
38
+ // Play animation backwards and forwards for full flip
39
+ if (animationType == "half_flip" ) {
40
+ print ('half line 40' );
41
+ if (status == AnimationStatus .completed) {
42
+ setState (() {
43
+ controller.repeat ();
44
+ });
45
+ }
46
+ }
47
+ // play animation on repeat for half flip
48
+ else if (animationType == "full_flip" ) {
49
+ print ('full line 57' );
50
+ if (status == AnimationStatus .completed) {
51
+ setState (() {
52
+ controller.reverse ();
53
+ });
54
+ }
55
+ if (status == AnimationStatus .dismissed) {
56
+ setState (() {
57
+ controller.forward ();
58
+ });
59
+ }
60
+ }
61
+ // custom animation state
62
+ else {
63
+ print ("TODO not sure yet" );
39
64
}
40
65
});
41
66
42
67
controller.forward ();
43
68
}
44
69
70
+ AnimationController createAnimationController ([String type = 'full_flip' ]) {
71
+ AnimationController animCtrl;
72
+
73
+ switch (type) {
74
+ case "half_flip" :
75
+ animCtrl = AnimationController (duration: const Duration (milliseconds: 2000 ), vsync: this );
76
+
77
+ // Horizontal animation
78
+ this .rotationHorizontal = Tween <double >(begin: 0.0 , end: 1.0 ).animate (
79
+ CurvedAnimation (
80
+ parent: animCtrl,
81
+ curve: Interval (0.0 , 0.50 , curve: Curves .fastOutSlowIn)));
82
+
83
+ // Vertical animation
84
+ this .rotationVertical = Tween <double >(begin: 0.0 , end: 1.0 ).animate (
85
+ CurvedAnimation (
86
+ parent: animCtrl,
87
+ curve: Interval (0.50 , 1.0 , curve: Curves .fastOutSlowIn)));
88
+ break ;
89
+ case "full_flip" :
90
+ default :
91
+ animCtrl = AnimationController (duration: const Duration (milliseconds: 4000 ), vsync: this );
92
+
93
+ this .rotationHorizontal = Tween <double >(begin: - 1.0 , end: 1.0 ).animate (
94
+ CurvedAnimation (
95
+ parent: animCtrl,
96
+ curve: Interval (0.0 , 0.50 , curve: Curves .linear)));
97
+ this .rotationVertical = Tween <double >(begin: - 1.0 , end: 1.0 ).animate (
98
+ CurvedAnimation (
99
+ parent: animCtrl,
100
+ curve: Interval (0.50 , 1.0 , curve: Curves .linear)));
101
+ break ;
102
+ }
103
+
104
+ return animCtrl;
105
+ }
106
+
45
107
@override
46
108
Widget build (BuildContext context) {
109
+ if (animationType == "half_flip" ) {
110
+ return buildFullFlipper (context);
111
+ } else {
112
+ return buildHalfFlipper (context);
113
+ }
114
+ }
115
+
116
+ Widget buildHalfFlipper (BuildContext context) {
47
117
return new AnimatedBuilder (
48
118
animation: controller,
49
119
builder: (BuildContext context, Widget child) {
@@ -57,15 +127,15 @@ class _FlipLoaderState extends State<FlipLoader>
57
127
child: Container (
58
128
decoration: BoxDecoration (
59
129
borderRadius: new BorderRadius .all (const Radius .circular (8.0 )),
60
- color: Colors .redAccent ,
130
+ color: loaderColor ,
61
131
),
62
132
width: 40.0 ,
63
133
height: 40.0 ,
64
134
child: new RotationTransition (
65
135
turns: rotationHorizontal.value == 1.0 ? rotationVertical : rotationHorizontal,
66
136
child: Icon (
67
- Icons . sync ,
68
- color: Colors .white ,
137
+ icon ,
138
+ color: iconColor ,
69
139
size: 20.0 ,
70
140
),
71
141
)
@@ -75,4 +145,34 @@ class _FlipLoaderState extends State<FlipLoader>
75
145
},
76
146
);
77
147
}
148
+
149
+ Widget buildFullFlipper (BuildContext context) {
150
+ return new AnimatedBuilder (
151
+ animation: controller,
152
+ builder: (BuildContext context, Widget child) {
153
+ return Container (
154
+ child: new Transform (
155
+ transform: Matrix4 .identity ()
156
+ ..setEntry (3 , 2 , 0.006 )
157
+ ..rotateX ((pi * rotationVertical.value))
158
+ ..rotateY ((pi * rotationHorizontal.value)),
159
+ alignment: Alignment .center,
160
+ child: Container (
161
+ decoration: BoxDecoration (
162
+ borderRadius: new BorderRadius .all (const Radius .circular (8.0 )),
163
+ color: loaderColor,
164
+ ),
165
+ width: 40.0 ,
166
+ height: 40.0 ,
167
+ child: new Center (
168
+ child: Icon (
169
+ icon, color: iconColor
170
+ ),
171
+ ),
172
+ ),
173
+ ),
174
+ );
175
+ },
176
+ );
177
+ }
78
178
}
0 commit comments