├── README.md ├── rainbow_text ├── README.md └── visual_view.dart ├── scale_animation ├── README.md └── scale_animation.dart ├── size_animation ├── README.md └── size_animation.dart ├── slider_animation ├── README.md └── adapter_view.dart └── widgets_animation ├── README.md └── everything_view.dart /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 |
4 | Markdownify 5 |
6 | Flutter Animations 7 |
8 |

9 | 10 | 11 | 12 | 13 |

In this repository I will keep some animations that I made during studies.

14 | 15 | ## How To Use 16 | 17 | Navigate between the repository folders, in each of them you will have a README file that will show the animation and the code responsible for it 18 | -------------------------------------------------------------------------------- /rainbow_text/README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 |
4 | Markdownify 5 |
6 | Rainbow Text 7 |
8 |

9 | 10 | 11 | https://user-images.githubusercontent.com/57817746/189343934-1ddaf774-29c6-4a08-9e34-926869604618.mov 12 | -------------------------------------------------------------------------------- /rainbow_text/visual_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_animate/flutter_animate.dart'; 3 | 4 | class VisualView extends StatelessWidget { 5 | const VisualView({Key? key}) : super(key: key); 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | // create our stylish text: 10 | Widget title = const Text( 11 | 'SOME\nVISUAL\nEFFECTS\n\n on\n\nRAINBOW\nTEXT', 12 | style: TextStyle( 13 | fontWeight: FontWeight.w900, 14 | fontSize: 64, 15 | color: Color(0xFF666870), 16 | height: 0.9, 17 | letterSpacing: -5, 18 | ), 19 | ); 20 | 21 | // add a rainbow gradient: 22 | // I'm lazy so I'll just apply a ShimmerEffect, use a ValueAdapter to 23 | // pause it half way, and let it handle the details 24 | title = title.animate(adapter: ValueAdapter(0.5)).shimmer( 25 | colors: [ 26 | const Color(0xFFFFFF00), 27 | const Color(0xFF00FF00), 28 | const Color(0xFF00FFFF), 29 | const Color(0xFF0033FF), 30 | const Color(0xFFFF00FF), 31 | const Color(0xFFFF0000), 32 | const Color(0xFFFFFF00), 33 | ], 34 | ); 35 | 36 | // sequence some visual effects 37 | title = title 38 | .animate(onPlay: (controller) => controller.repeat(reverse: true)) 39 | .saturate(delay: 1.seconds, duration: 2.seconds) 40 | .then() // set delay to when the previous effect ends. 41 | .tint(color: const Color(0xFF80DDFF)) 42 | .then() 43 | .blur(end: 24) 44 | .fadeOut(); 45 | 46 | return Padding(padding: const EdgeInsets.all(24), child: title); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /scale_animation/README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 |
4 | Markdownify 5 |
6 | Scale Animation 7 |
8 |

9 | 10 | https://user-images.githubusercontent.com/57817746/189344175-bed69578-74f7-4069-abf8-6bb829cc64ab.mov 11 | -------------------------------------------------------------------------------- /scale_animation/scale_animation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | ///Animates the child 4 | /// 5 | ///using TweenAnimationBuilder 6 | class ScaleAnimation extends StatelessWidget { 7 | const ScaleAnimation({ 8 | Key? key, 9 | required this.child, 10 | this.begin = 0.4, 11 | this.end = 1, 12 | this.intervalStart = 0, 13 | this.intervalEnd = 1, 14 | this.duration = const Duration(milliseconds: 1000), 15 | this.curve = Curves.fastOutSlowIn, 16 | }) : super(key: key); 17 | 18 | ///Animate from value 19 | /// 20 | ///[default value 0.4] 21 | final double begin; 22 | 23 | ///Animate to value 24 | /// 25 | ///[default value 1] 26 | final double end; 27 | 28 | ///Animation Duration 29 | /// 30 | ///[default is 750ms] 31 | final Duration duration; 32 | 33 | ///Animation delay 34 | /// 35 | ///[default is 0] 36 | final double intervalStart; 37 | 38 | ///Animation delay 39 | /// 40 | ///[default is 1] 41 | final double intervalEnd; 42 | 43 | ///Animation Curve 44 | /// 45 | ///[default is Curves.fastOutSlowIn] 46 | final Curve curve; 47 | 48 | ///This widget will be animated 49 | final Widget child; 50 | 51 | @override 52 | Widget build(BuildContext context) { 53 | return TweenAnimationBuilder( 54 | tween: Tween(begin: begin, end: end), 55 | duration: duration, 56 | curve: Interval(intervalStart, intervalEnd, curve: curve), 57 | child: child, 58 | builder: (BuildContext context, double? value, Widget? child) { 59 | return Transform.scale( 60 | scale: value!, 61 | child: child, 62 | ); 63 | }, 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /size_animation/README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 |
4 | Markdownify 5 |
6 | Scale Animation 7 |
8 |

9 | 10 | 11 | https://user-images.githubusercontent.com/57817746/188716593-e5db801e-569f-4230-820e-c22f8ee73dfd.mov 12 | -------------------------------------------------------------------------------- /size_animation/size_animation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class SizeAnimation extends StatefulWidget { 4 | const SizeAnimation({Key? key}) : super(key: key); 5 | 6 | @override 7 | State createState() => _SizeAnimationState(); 8 | } 9 | 10 | class _SizeAnimationState extends State { 11 | double _size = 300; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | body: Center( 17 | child: GestureDetector( 18 | onTap: () { 19 | setState(() { 20 | _size = _size == 300 ? 100 : 300; 21 | }); 22 | }, 23 | child: Container( 24 | color: Colors.white, 25 | child: AnimatedSize( 26 | curve: Curves.easeIn, 27 | child: FlutterLogo( 28 | size: _size, 29 | ), 30 | duration: Duration(seconds: 1), 31 | ), 32 | ), 33 | ), 34 | ), 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /slider_animation/README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 |
4 | Markdownify 5 |
6 | Slider Animation 7 |
8 |

9 | 10 | 11 | https://user-images.githubusercontent.com/57817746/189345052-3e9157b8-913b-4f0e-a1aa-3432ba40fc86.mov 12 | 13 | -------------------------------------------------------------------------------- /slider_animation/adapter_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_animate/flutter_animate.dart'; 3 | 4 | class AdapterView extends StatelessWidget { 5 | const AdapterView({Key? key}) : super(key: key); 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | // example of driving an animation with a ValueNotifier 10 | 11 | // create the ValueNotifier: 12 | ValueNotifier notifier = ValueNotifier(0); 13 | 14 | // create an overly elaborate animation using ValueNotifierAdapter, 15 | // and wire up a Slider to update the ValueNotifier 16 | Widget panel = Container( 17 | color: const Color(0xFF2A2B2F), 18 | child: Column(children: [ 19 | const SizedBox(height: 32), 20 | const Text( 21 | 'Slider Driven Animation', 22 | style: TextStyle( 23 | fontSize: 36, 24 | fontWeight: FontWeight.bold, 25 | height: 1, 26 | ), 27 | textAlign: TextAlign.center, 28 | ) 29 | .animate(adapter: ValueNotifierAdapter(notifier)) 30 | .blur(end: 16) 31 | .scale(begin: 1, end: 2) 32 | .tint(color: const Color(0xFF80DDFF)) 33 | .fadeOut(curve: Curves.easeInExpo), 34 | 35 | // Slider: 36 | AnimatedBuilder( 37 | animation: notifier, 38 | builder: (_, __) => Slider( 39 | activeColor: const Color(0xFF80DDFF), 40 | value: notifier.value, 41 | onChanged: (value) => notifier.value = value, 42 | ), 43 | ) 44 | ]), 45 | ); 46 | 47 | // example driving animations with a ScrollController 48 | 49 | // create the scroll controller: 50 | ScrollController scrollController = ScrollController(); 51 | 52 | // create some dummy items for the list: 53 | List items = [ 54 | const Text( 55 | 'Scroll driven animation', 56 | style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18), 57 | ) 58 | ]; 59 | for (int i = 0; i < 100; i++) { 60 | items.add(Text('item $i', style: const TextStyle(height: 2.5))); 61 | } 62 | // layer the indicators under the list, and assign the ScrollController to 63 | // the list, and both animations (via ScrollAdapter): 64 | Widget list = Stack( 65 | children: [ 66 | Container( 67 | height: 64, 68 | decoration: const BoxDecoration( 69 | gradient: LinearGradient( 70 | begin: Alignment.topCenter, 71 | end: Alignment.bottomCenter, 72 | colors: [Color(0x8080DDFF), Colors.transparent]), 73 | ), 74 | ) 75 | .animate(adapter: ScrollAdapter(scrollController, end: 500)) // 76 | .fadeIn(), 77 | 78 | // bottom indicator: 79 | Align( 80 | alignment: Alignment.bottomCenter, 81 | child: Container( 82 | height: 64, 83 | decoration: const BoxDecoration( 84 | gradient: LinearGradient( 85 | begin: Alignment.bottomCenter, 86 | end: Alignment.topCenter, 87 | colors: [Color(0x8080DDFF), Colors.transparent], 88 | ), 89 | ), 90 | ) 91 | .animate(adapter: ScrollAdapter(scrollController, begin: -500)) 92 | .fadeOut(), 93 | ), 94 | 95 | // the list (with the scrollController assigned): 96 | ListView( 97 | padding: const EdgeInsets.all(24.0), 98 | controller: scrollController, 99 | children: items, 100 | ), 101 | ], 102 | ); 103 | 104 | return Column( 105 | children: [ 106 | panel, 107 | Flexible(child: list), 108 | ], 109 | ); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /widgets_animation/README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 |
4 | Markdownify 5 |
6 | Widgets Animations 7 |
8 |

9 | 10 | 11 | https://user-images.githubusercontent.com/57817746/189347999-84e06a6a-e3e3-4bb9-bcf1-5e27a590cb1c.mov 12 | 13 | -------------------------------------------------------------------------------- /widgets_animation/everything_view.dart: -------------------------------------------------------------------------------- 1 | // Kitchen sink view of all Effects 2 | 3 | import 'dart:math'; 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_animate/flutter_animate.dart'; 7 | 8 | class EverythingView extends StatelessWidget { 9 | const EverythingView({Key? key}) : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return LayoutBuilder( 14 | builder: (_, box) => GridView.count( 15 | crossAxisCount: (box.maxWidth / 128).floor(), 16 | childAspectRatio: 0.8, 17 | children: [ 18 | // these are in alphabetic order according to their classes 19 | // ex. BlurEffect defines both blur and unblur. 20 | 21 | tile("blur", a.blur()), 22 | tile("unblur", a.unblur()), 23 | 24 | // callback? 25 | 26 | tile("custom", a.custom(builder: (_, val, child) { 27 | val = val * pi * 2 - pi / 2; 28 | return Transform.translate( 29 | offset: Offset(cos(val) * 24, sin(val) * 24), 30 | child: Transform.scale(scale: 0.66, child: child), 31 | ); 32 | })), 33 | 34 | tile("fadeIn", a.fadeIn()), 35 | tile("fadeOut", a.fadeOut()), 36 | 37 | // listen? 38 | 39 | tile("move", a.move()), 40 | 41 | tile("rotate", a.rotate()), 42 | 43 | tile("saturate", a.saturate()), 44 | tile("desaturate", a.desaturate()), 45 | 46 | tile("scale", a.scale()), 47 | 48 | tile("shake", a.shake()), 49 | tile("shakeX", a.shakeX()), 50 | tile("shakeY", a.shakeY()), 51 | 52 | tile("shimmer", a.shimmer()), 53 | 54 | tile("slide", a.slide()), 55 | 56 | tile("swap", a.swap(builder: (_, __) => const Text("HELLO!"))), 57 | tile("swap (child)", a.swap(builder: (_, child) { 58 | return Opacity(opacity: 0.5, child: child!); 59 | })), 60 | 61 | // then? 62 | 63 | tile("tint", a.tint()), 64 | tile("untint", a.untint()), 65 | 66 | tile("toggle", a.toggle(builder: (_, b, child) { 67 | return Container( 68 | color: b ? Colors.purple : Colors.yellow, 69 | padding: const EdgeInsets.all(8), 70 | child: child, 71 | ); 72 | })), 73 | 74 | tile("hide", a.hide()), 75 | tile("show", a.show()), 76 | ], 77 | ), 78 | ); 79 | } 80 | 81 | // this returns a ready to use Animate instance targeting a `box` (see below) 82 | // it uses empty effects to set default delay/duration values (750 & 1500ms) 83 | // and a total duration (3000ms), so there is a 750ms pause at the end. 84 | Animate get a => box 85 | .animate(onPlay: (controller) => controller.repeat()) 86 | .effect(duration: 3000.ms) // this "pads out" the total duration 87 | .effect(delay: 750.ms, duration: 1500.ms); // set defaults 88 | 89 | // simple square box with a gradient to use as the target for animations. 90 | Widget get box => Container( 91 | decoration: const BoxDecoration( 92 | gradient: LinearGradient( 93 | colors: [Colors.red, Colors.green, Colors.blue], 94 | begin: Alignment.topLeft, 95 | end: Alignment.bottomRight, 96 | ), 97 | ), 98 | width: 64, 99 | height: 64, 100 | ); 101 | 102 | // grid tile. Naming should be `buildTile`, but going for brevity. 103 | Widget tile(String label, Widget demo) => Container( 104 | margin: const EdgeInsets.all(4), 105 | color: Colors.black12, 106 | height: 160, 107 | child: Column( 108 | children: [ 109 | Flexible(child: Center(child: demo)), 110 | Container( 111 | color: Colors.black12, 112 | height: 32, 113 | alignment: Alignment.center, 114 | child: Text(label, style: const TextStyle(fontSize: 12)), 115 | ) 116 | ], 117 | ), 118 | ); 119 | } 120 | --------------------------------------------------------------------------------