Created
March 11, 2021 20:58
-
-
Save chinloyal/21038022f0edc68e7ba3d1cd8a36f1c1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:math' as math show sin, pi; | |
import 'package:flutter/animation.dart'; | |
import 'package:flutter/material.dart'; | |
final Color darkBlue = Color.fromARGB(255, 18, 32, 47); | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue), | |
debugShowCheckedModeBanner: false, | |
home: Scaffold( | |
body: Center( | |
child: ThreeBounce( | |
color: Colors.red, | |
), | |
), | |
), | |
); | |
} | |
} | |
class ThreeBounce extends StatefulWidget { | |
const ThreeBounce({ | |
this.color, | |
this.size = 50.0, | |
this.itemBuilder, | |
this.duration = const Duration(milliseconds: 1400), | |
this.controller, | |
}) : assert( | |
!(itemBuilder is IndexedWidgetBuilder && color is Color) && | |
!(itemBuilder == null && color == null), | |
'You should specify either a itemBuilder or a color'); | |
final Color color; | |
final double size; | |
final IndexedWidgetBuilder itemBuilder; | |
final Duration duration; | |
final AnimationController controller; | |
@override | |
_ThreeBounceState createState() => _ThreeBounceState(); | |
} | |
class _ThreeBounceState extends State<ThreeBounce> | |
with SingleTickerProviderStateMixin { | |
AnimationController _controller; | |
@override | |
void initState() { | |
super.initState(); | |
_controller = (widget.controller ?? | |
AnimationController(vsync: this, duration: widget.duration)) | |
..repeat(); | |
} | |
@override | |
void dispose() { | |
_controller.dispose(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Center( | |
child: SizedBox.fromSize( | |
size: Size(widget.size * 2, widget.size), | |
child: Row( | |
mainAxisAlignment: MainAxisAlignment.spaceEvenly, | |
children: List.generate(3, (i) { | |
return ScaleTransition( | |
scale: DelayTween(begin: 0.0, end: 1.0, delay: i * .2) | |
.animate(_controller), | |
child: SizedBox.fromSize( | |
size: Size.square(widget.size * 0.5), child: _itemBuilder(i)), | |
); | |
}), | |
), | |
), | |
); | |
} | |
Widget _itemBuilder(int index) => widget.itemBuilder != null | |
? widget.itemBuilder(context, index) | |
: DecoratedBox( | |
decoration: | |
BoxDecoration(color: widget.color, shape: BoxShape.circle)); | |
} | |
class DelayTween extends Tween<double> { | |
DelayTween({double begin, double end, @required this.delay}) | |
: super(begin: begin, end: end); | |
final double delay; | |
@override | |
double lerp(double t) => | |
super.lerp((math.sin((t - delay) * 2 * math.pi) + 1) / 2); | |
@override | |
double evaluate(Animation<double> animation) => lerp(animation.value); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You solved my problem today.
Thank you very much.