Last active
January 31, 2022 05:28
-
-
Save esDotDev/aad7ed6889dd275921881383a23ce439 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
/// Example usage | |
/// | |
/// One shot: | |
// GTweener.fade(from: .9, to: 1, child: const FlutterLogo()), | |
/// | |
/// Or use a key for future control | |
// final _tweenKey = GlobalKey<GTweenerState>(); | |
// ... | |
// return GTweener.fade(key: _tweenKey, child: const FlutterLogo()), | |
// ... | |
// onPressed: () => _tweenKey.currentState!.anim.reverse(from: 1); | |
class TweenExamples extends StatelessWidget { | |
final _tweenKey = GlobalKey<GTweenerState>(); | |
AnimationController get _tween => _tweenKey.currentState!.anim; | |
@override | |
Widget build(BuildContext context) { | |
return Center( | |
child: Column( | |
mainAxisSize: MainAxisSize.min, | |
children: [ | |
GTweener.fade(key: _tweenKey, child: const FlutterLogo()), | |
TextButton( | |
onPressed: () => _tween.forward(from: 0), | |
child: const Text('Run Again'), | |
) | |
], | |
), | |
); | |
} | |
} | |
class GTweener<T> extends StatefulWidget { | |
static const _defaultDuration = Duration(milliseconds: 300); | |
const GTweener( | |
this.builder, { | |
required this.child, | |
this.duration = _defaultDuration, | |
this.autoPlay = true, | |
this.from, | |
required this.to, | |
Key? key, | |
}) : super(key: key); | |
final Widget Function(BuildContext context, Widget child, AnimationController anim) builder; | |
final Widget child; | |
final Duration duration; | |
final bool autoPlay; | |
final T? from; | |
final T? to; | |
@override | |
State<GTweener> createState() => GTweenerState(); | |
static Widget _fadeBuilder(BuildContext context, Widget child, AnimationController anim) => FadeTransition( | |
opacity: anim, | |
child: child, | |
); | |
static GTweener<double> fade({ | |
required Widget child, | |
Duration duration = _defaultDuration, | |
bool autoPlay = true, | |
double? from, | |
double? to, | |
Key? key, | |
}) { | |
return GTweener( | |
_fadeBuilder, | |
key: key, | |
child: child, | |
duration: duration, | |
autoPlay: autoPlay, | |
// TODO: handle from / to somehow, need to figure out how we want to map the controller upper and lower bounds | |
from: from, | |
to: to, | |
); | |
} | |
} | |
class GTweenerState extends State<GTweener> with SingleTickerProviderStateMixin { | |
late final AnimationController anim = AnimationController( | |
vsync: this, | |
duration: widget.duration, | |
); | |
@override | |
void initState() { | |
super.initState(); | |
if (widget.autoPlay) anim.forward(); | |
} | |
@override | |
Widget build(BuildContext context) => widget.builder(context, widget.child, anim); | |
} | |
/* | |
// Alternate API style: | |
GFade.tween(to: 1, key: gTween, child: FlutterLogo()), | |
// Some extension ideas: | |
FlutterLogo().gFade(to: 1), | |
FlutterLogo().gMultiTweener([ | |
GTweener.fade(to: 1), | |
GTweener.scale(to: 1) | |
]), | |
/* | |
GTweener API Spec TODO, | |
config: | |
// autoPlay | |
// duration | |
* delay | |
* reflect | |
* ease | |
* timeScale | |
events | |
* onChange | |
* onComplete | |
* onInit | |
*/ | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment