{"id":15294716,"url":"https://github.com/norbert515/flutter_villains","last_synced_at":"2025-04-05T20:09:41.323Z","repository":{"id":49679491,"uuid":"136000528","full_name":"Norbert515/flutter_villains","owner":"Norbert515","description":"Flexible and easy to use page transitions.","archived":false,"fork":false,"pushed_at":"2022-08-26T08:08:49.000Z","size":400,"stargazers_count":365,"open_issues_count":5,"forks_count":35,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-05T20:09:36.626Z","etag":null,"topics":["animation","flutter","transitions","villains"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Norbert515.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-06-04T09:15:48.000Z","updated_at":"2024-10-23T16:12:05.000Z","dependencies_parsed_at":"2022-09-09T17:11:25.422Z","dependency_job_id":null,"html_url":"https://github.com/Norbert515/flutter_villains","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Norbert515%2Fflutter_villains","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Norbert515%2Fflutter_villains/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Norbert515%2Fflutter_villains/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Norbert515%2Fflutter_villains/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Norbert515","download_url":"https://codeload.github.com/Norbert515/flutter_villains/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247393574,"owners_count":20931813,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","flutter","transitions","villains"],"created_at":"2024-09-30T17:06:28.730Z","updated_at":"2025-04-05T20:09:41.291Z","avatar_url":"https://github.com/Norbert515.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![license](https://img.shields.io/github/license/Norbert515/flutter_villains.svg)](https://github.com/Norbert515/flutter_villains/blob/master/LICENSE)\n[![stars](https://img.shields.io/github/stars/Norbert515/flutter_villains.svg)](https://github.com/Norbert515/flutter_villains/stargazers)\n[![forks](https://img.shields.io/github/forks/Norbert515/flutter_villains.svg)](https://github.com/Norbert515/flutter_villains/network/members)\n[![Pub](https://img.shields.io/pub/v/flutter_villains.svg)](https://pub.dartlang.org/packages/flutter_villains)\n[![GitHub followers](https://img.shields.io/github/followers/norbert515.svg?style=social\u0026label=Follow)](https://github.com/Norbert515)\n[![Twitter Follow](https://img.shields.io/twitter/follow/norbertkozsir.svg?style=social\u0026label=Follow)](https://twitter.com/norbertkozsir)\n[![Build Status](https://travis-ci.com/Norbert515/flutter_villains.svg?branch=master)](https://travis-ci.com/Norbert515/flutter_villains)\n\n\n![](https://github.com/Norbert515/flutter_villains/blob/master/assets/icons8-joker-suicide-squad-96.png)\n# flutter_villains\n\n### What are heroes without villains?\n\n![profile-page](media/profile.gif \"profile-page\")\n\n_(Profile image from: https://unsplash.com/photos/pAs4IM6OGWI)_\n\n_Check out the [article](https://medium.com/flutter-community/flutter-heroes-and-villains-bringing-balance-to-the-flutterverse-2e900222de41)._\n\n## What are villains?\nYou keep seeing beautiful page transitions but you think to yourself those are too much work?\n\nFear no more, villains are here to save you!\n\nWhen doing animations when a page transition occurs you'd usally define an `AnimationController` in the `initState()` and start it there. You'd also have to wrap your widgets in `AnimatedWidgets` to react to the `AnimationController`. Besides this being a lot of boilerplate code which clogs up you precious widgets, animating on exit isn't as trivial.\n\nUsing this library you just wrap your widget you'd like to be animated when a page transition occurs in a `Villain` and everything is handled automatically.\n\n## Installation\n```\ndependencies:\n  flutter_villains: \"^1.2.1\"\n```\nRun packages get and **import**:\n```\nimport 'package:flutter_villains/villain.dart';\n```\n\n### Assembling pages with style\nDefine animations to play when a page is opened.\n\n### Easy to use \n```dart\n      Villain(\n        villainAnimation: VillainAnimation.fromBottom(\n          relativeOffset: 0.4,\n          from: Duration(milliseconds: 100),\n          to: Duration(seconds: 1),\n        ),\n        animateExit: false,\n        secondaryVillainAnimation: VillainAnimation.fade(),\n        child: Divider(\n          color: Colors.black,\n          height: 32.0,\n        ),\n      ),\n```\nThat's it. No `TickerProvider`s, no `AnimationController`s, no boilerplate, no worries.\nRemember the StaggeredAnimation tutorial? This is using [SequenceAnimation](https://github.com/Norbert515/flutter_sequence_animation) internally and there is therefore no need to specify durations as portions of a time-frame. It just works. \n\nWith this basic setup the `Divider` fades in and moves up when a page transition occures (don't forget the `VillainTransitionObserver` more on that under *Code*).\n\n### Flexible \nThe animation you'd like to use is not premade? Make it yourself with a few lines of code!\n\n```dart\n  static VillainAnimation fade(\n          {double fadeFrom = 0.0,\n          double fadeTo = 1.0,\n          Duration from = Duration.zero,\n          Duration to: _kMaterialRouteTransitionLength,\n          Curve curve: Curves.linear}) =\u003e\n      VillainAnimation(\n          from: from,\n          curve: curve,\n          to: to,\n          animatable: Tween\u003cdouble\u003e(begin: fadeFrom, end: fadeTo),\n          animatedWidgetBuilder: (animation, child) {\n            return FadeTransition(\n              opacity: animation,\n              child: child,\n            );\n          });\n```\nEvery `VillainAnimation` needs an `Animatable` (most of the time it's a `Tween`) and an `AnimatedWidget`. Everything else is handled automatically.\n\n\n## Code\n\nThere are two way of playing your villains.\n\n1) If you want them to automatically play when a page transition occurs (you probably want that) then add this to your `MaterialApp`\n```dart\n    return new MaterialApp(\n      navigatorObservers: [new VillainTransitionObserver()],\n```\n\n2) Play villains in a given context manually.\n```dart\n    VillainController.playAllVillains(context);\n```\n\n\n### Secondary Animation\nYou can play up to two animations per `Villain`. You can always wrap Villains inside each other for _infinite_ animations!\n```dart\n    Villain(\n      villainAnimation: VillainAnimation.fromBottomToTop(0.4, to: Duration(milliseconds: 150)),\n      animateExit: false,\n      secondaryVillainAnimation: VillainAnimation.fade,\n      child: Text(\n        \"Hi\",\n        style: Theme.of(context).textTheme.body1,\n      ),\n    ),\n```\n\n### Extras\nDefine whether the villain should play on entrance/ exit.\n```dart\n    animateEntrance: true,\n    animateExit: true,\n```\nWhen using the `VillainController` manually, it checks this bool to determine whether it should animate. \n```dart\n  static Future playAllVillains(BuildContext context, {bool entrance = true})\n```\n\nVillains entering the page are decoupled from the page transition, meaning they can be as long as they \nwant. On the other hand, if a villain leaves the page, the animation is driven by the page transition.\nThis means:\n - The exit animation is always as long a the exit page transition\n - Setting the duration doesn't change anything\n \n\n## Examples\nTake a look at the example folder for three nice examples.\n\n## Features:\nThe villain framework takes care of:\n- managing page transition callbacks\n- supplying animations\n- providing premade common animations\n\nIn contrast to real world villains, these villains are **very** easy to handle.\n\n\n\n## Controller\nCurrenty there are no controllers implemented to play individual villains by themselves. If you'd like to have that implemented I opened an issue discussing it. Check it out!\n\n\n\n\nIcon from https://icons8.com/ \n\n## Getting Started\n\nFor help getting started with Flutter, view our online [documentation](https://flutter.io/).\n\nFor help on editing package code, view the [documentation](https://flutter.io/developing-packages/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnorbert515%2Fflutter_villains","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnorbert515%2Fflutter_villains","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnorbert515%2Fflutter_villains/lists"}