heroine 0.5.0+1 copy "heroine: ^0.5.0+1" to clipboard
heroine: ^0.5.0+1 copied to clipboard

The queen of hero transitions. Flutter's most addictive interactions.

Heroine #

Code Coverage Powered by Mason lints by lintervention Bluesky

The queen of hero transitions. Flutter's most addictive interactions.

Showcase GIF

"this will be such an addictive #FlutterDev interaction!"

~ Mike Rydstrom

Features 🎯 #

  • 🌊 Smooth spring-based hero transitions with customizable bounce and duration
  • πŸ”„ Drag-to-dismiss gestures with velocity-aware animations
  • 🎨 Beautiful transition effects with customizable shuttle builders
  • πŸ“± Route-aware transitions that adapt to navigation gestures
  • 🎯 Seamless integration with Flutter's navigation system

Try it out #

Open Example

Installation πŸ’» #

❗ In order to start using Heroine you must have the Flutter SDK installed on your machine.

Add to your pubspec.yaml:

dependencies:
  heroine: ^latest_version

Or install via flutter pub:

flutter pub add heroine

Usage πŸ’‘ #

Set up HeroineController for your app #

To use heroines in your app, it is important that you register a HeroineController in your app's navigator.

MaterialApp( // or CupertinoApp, or WidgetsApp
  home: MyHomePage(),
  navigatorObservers: [HeroineController()],
)

Note: In some nested routing scenarios, HeroineController might have to be registered in all of the nested navigators as well.

Basic Hero Transition #

Use Heroine for spring-based hero transitions between routes, just like you would with the Hero widget:

// In the source route
Heroine(
  tag: 'unique-tag',
  child: MyWidget(),
)

// In the destination route
Heroine(
  tag: 'unique-tag',
  child: MyExpandedWidget(),
)

Custom Transition Effects #

Choose from predefined shuttle builders or create your own:

Heroine(
  tag: 'unique-tag',
  flightShuttleBuilder: const FlipShuttleBuilder(
    axis: Axis.vertical,
    halfFlips: 1,
  ),
  motion: Motion.bouncySpring(),
  child: MyWidget(),
)

Available shuttle builders:

  • FadeShuttleBuilder - Smooth fade transition between heroes
  • FlipShuttleBuilder - 3D flip animation with customizable axis and direction
  • SingleShuttleBuilder - Only displays the destination widget – like Flutter's default hero transition
  • FadeThroughShuttleBuilder - Fades through a specified color during transition
  • ChainedShuttleBuilder - Combines multiple shuttle builders for complex effects
  • HeroineShuttleBuilder.fromHero() - Use existing HeroFlightShuttleBuilder implementations

Chaining Multiple Effects

Combine multiple shuttle builders for complex transitions:

Heroine(
  tag: 'unique-tag',
  flightShuttleBuilder: const FlipShuttleBuilder()
    .chain(const FadeShuttleBuilder()),
  // or using ChainedShuttleBuilder directly:
  // flightShuttleBuilder: const ChainedShuttleBuilder(
  //   builders: [FlipShuttleBuilder(), FadeShuttleBuilder()],
  // ),
  child: MyWidget(),
)

Custom Color Fade Through

Fade through a specific color during transition:

Heroine(
  tag: 'unique-tag',
  flightShuttleBuilder: const FadeThroughShuttleBuilder(
    fadeColor: Colors.white,
  ),
  child: MyWidget(),
)

Drag-to-Dismiss #

Enable drag-to-dismiss gestures with spring return animations, by wrapping your Heroine in a DragDismissable widget:

DragDismissable(
  onDismiss: () => Navigator.pop(context),
  child: Heroine(
    tag: 'unique-tag',
    child: MyWidget(),
  ),
)

Fullscreen Transitions (aka Container Transform) #

Like with Flutter's default hero transition, heroine does not support nested transitions.

Unlike Flutter however, it will allow you to nest heroines, as long as they are not part of the same transition. This allows you to have fullscreen transitions, in multiple, nested routes like in the fullscreen example.

Fullscreen Example

Check out the fullscreen example code: full_screen.dart.

Heroine-aware routes #

Make your routes respond to Heroine dismiss gestures:

class MyCustomRoute<T> extends PageRoute<T> with HeroinePageRouteMixin {
  // ... your route implementation, see example for more details
}

// React to dismiss gestures in your UI
ReactToHeroineDismiss(
  builder: (context, progress, offset, child) {
    return Opacity(
      opacity: 1 - progress,
      child: child,
    );
  },
  child: MyWidget(),
)

This will fade out MyWidget progressively, as the user dismisses the heroine.

If you look closely at the example GIF, you will see that the details page fades out as the user drags the heroine away.

Warning: While Heroine throws an assertion error if it detects that you are trying to fly two nested heroines at the same time, it can't check for this in release builds, since it needs to walk the widget tree. If you miss an occurrence of this, it will break your heroine transitions.

Motion Configuration 🎯 #

Heroine uses Motor for motion animations. You can customize the motion:

final springMotion = Motion.spring(
  Spring.withDurationAndBounce(
    duration: Duration(milliseconds: 500), 
    bounce: 0.5,
  ),
);

final cupertinoMotion = CupertinoMotion.smooth();

final linearMotion = Motion.linear(Duration(milliseconds: 300));

final ease = Motion.curved(Duration(milliseconds: 300), Curves.easeInOut);

// Then pass it to the Heroine widget
return Heroine(
  tag: 'unique-tag',
  motion: springMotion,
  child: MyWidget(),
);

Advanced Features πŸš€ #

Velocity-Aware Transitions #

Provide velocity information for smoother transitions from gestures using HeroineVelocity:

HeroineVelocity(
  velocity: dragVelocity,
  child: Heroine(
    tag: 'unique-tag',
    child: MyWidget(),
  ),
)

The HeroineVelocity widget automatically provides velocity context to any Heroine widgets below it in the widget tree. This is particularly useful when transitioning from gesture-based interactions.

Check out the implementation of DragDismissable, to see how that widget uses HeroineVelocity to pass the user's drag velocity to the heroine.

For full control however, just pass in a custom Motion to the Heroine widget with whatever duration you want.

Available Tools & Widgets πŸ› οΈ #

Core Widgets #

  • Heroine - The main hero widget with spring-based animations
  • HeroineController - Navigator observer for managing hero transitions
  • DragDismissable - Wrapper for drag-to-dismiss functionality
  • HeroineVelocity - Provides velocity context for gesture-based transitions
  • ReactToHeroineDismiss - Responds to dismiss gestures in your UI

Route Integration #

  • HeroinePageRouteMixin - Mixin for creating heroine-aware routes
  • HeroinePageRoute - Pre-built page route with heroine support

Shuttle Builders #

  • FadeShuttleBuilder - Cross-fade between heroes
  • FlipShuttleBuilder - 3D flip transitions (customizable axis, direction, and flip count)
  • SingleShuttleBuilder - Show only source or destination hero
  • FadeThroughShuttleBuilder - Fade through a specified color
  • ChainedShuttleBuilder - Combine multiple effects
  • HeroineShuttleBuilder.fromHero() - Adapter for existing Flutter hero builders
  • Extension methods - .chain() method for fluent builder chaining

Best Practices πŸ“ #

  1. Use unique tags for each hero pair
  2. Keep heroine widget's shapes similar in both routes
  3. Register HeroineController in your app's navigator observers
  4. Use HeroineVelocity for gesture-driven transitions
  5. Test transitions with different motion configurations
  6. Handle edge cases with custom shuttle builders
  7. Avoid nested heroines in the same transition

240
likes
160
points
1.36k
downloads

Publisher

verified publisherwhynotmake.it

Weekly Downloads

The queen of hero transitions. Flutter's most addictive interactions.

Homepage
Repository (GitHub)
View/report issues

Topics

#springs #animation #physics #hero

Documentation

API reference

License

MIT (license)

Dependencies

equatable, flutter, motor

More

Packages that depend on heroine