import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'dart:async'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp(home: Scaffold(body: App())); } } class App extends StatefulWidget { @override AppState createState() => AppState(); } class AppState extends State with TickerProviderStateMixin { AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( duration: Duration(seconds: 1), vsync: this, ); } @override void dispose() { _controller?.dispose(); super.dispose(); } Future _startAnim() async { try { await _controller.forward().orCancel; await _controller.reverse().orCancel; } on TickerCanceled { print('welp we fucked'); } } @override Widget build(BuildContext context) { timeDilation = 10.0; return MaterialApp( home: Scaffold( appBar: AppBar(), body: GestureDetector( onTap: () { _startAnim(); }, child: Center( child: Container( width: 350, height: 350, decoration: BoxDecoration( color: Colors.red.withOpacity(0.1), border: Border.all( color: Colors.blueGrey.withOpacity(0.8))), child: AnimatedBox( controller: _controller, )))))); } } class AnimatedBox extends StatelessWidget { AnimatedBox({Key key, this.controller}) : opacity = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation( parent: controller, curve: Interval(0.0, 0.1, curve: Curves.fastOutSlowIn))), rotate = Tween(begin: 0.0, end: 3.141 * 4).animate( CurvedAnimation( parent: controller, curve: Interval(0.1, 0.3, curve: Curves.ease))), movement = EdgeInsetsTween( begin: EdgeInsets.only(bottom: 10, left: 0.0), end: EdgeInsets.only(bottom: 100.0, left: 75.0)) .animate(CurvedAnimation( parent: controller, curve: Interval(0.3, 0.4, curve: Curves.fastOutSlowIn))), width = Tween(begin: 50.0, end: 200.0).animate(CurvedAnimation( parent: controller, curve: Interval(0.4, 0.6, curve: Curves.fastOutSlowIn))), height = Tween(begin: 50.0, end: 200.0).animate(CurvedAnimation( parent: controller, curve: Interval(0.4, 0.6, curve: Curves.fastOutSlowIn))), radius = BorderRadiusTween( begin: BorderRadius.circular(0.0), end: BorderRadius.circular(100.0)) .animate(CurvedAnimation( parent: controller, curve: Interval( 0.6, 0.75, curve: Curves.ease, ))), color = ColorTween(begin: Colors.red[200], end: Colors.deepPurple[900]) .animate(CurvedAnimation( parent: controller, curve: Interval(0.0, 0.75, curve: Curves.linear))), super(key: key); final Animation controller; final Animation opacity; final Animation width; final Animation height; final Animation movement; final Animation radius; final Animation color; final Animation rotate; @override Widget build(BuildContext context) { return AnimatedBuilder( animation: controller, builder: (BuildContext context, Widget child) { return Container( padding: movement.value, transform: Matrix4.identity()..rotateZ(rotate.value), alignment: Alignment.center, child: Opacity( opacity: opacity.value, child: Container( width: width.value, height: height.value, decoration: BoxDecoration( color: color.value, border: Border.all( color: Colors.cyan, width: 2.0, ), borderRadius: radius.value, ), )), ); }); } }