Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add optional useRepaintBoundary to Animate #47

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion lib/src/animate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ class Animate extends StatefulWidget with AnimateManager<Animate> {
/// ```
static bool restartOnHotReload = false;

/// Default setting for [useRepaintBoundary].
static const bool defaultUseRepaintBoundary = false;

/// Widget types to reparent, mapped to a method that handles that type. This is used
/// to make it easy to work with widgets that require specific parents. For example,
/// the [Positioned] widget, which needs its immediate parent to be a [Stack].
Expand Down Expand Up @@ -116,6 +119,7 @@ class Animate extends StatefulWidget with AnimateManager<Animate> {
this.controller,
this.adapter,
this.target,
this.useRepaintBoundary,
}) : super(key: key) {
_entries = [];
if (effects != null) addEffects(effects);
Expand Down Expand Up @@ -176,6 +180,30 @@ class Animate extends StatefulWidget with AnimateManager<Animate> {
/// ```
final double? target;

/// Wraps the [Animate] widget in a [RepaintBoundary].
///
/// **Use this carefully!**
///
/// This *can* improve performance when animating a widget on a complex view,
/// as it will prevent the entire view from being repainted when the animation
/// changes.
///
/// However, it also comes with a cost and should **not** be used on all
/// animations.
///
/// **Example of when to use**: Complex view with lots of widgets and a single
/// animation. \
/// **Example of when *not* to use**: View with many animations, where most
/// of the content needs to be repainted anyway when animating.
///
/// Visit the [RepaintBoundary] [documentation](https://api.flutter.dev/flutter/widgets/RepaintBoundary-class.html)
/// for more information or watch this [Widget of the Week video](https://www.youtube.com/watch?v=cVAGLDuc2xE).
///
/// As described in the linked video, you can set `debugRepaintRainbowEnabled = true`
/// before `runApp` to search for places where applying a [RepaintBoundary] would
/// be beneficial.
final bool? useRepaintBoundary;

late final List<EffectEntry> _entries;
Duration _duration = Duration.zero;
EffectEntry? _lastEntry;
Expand Down Expand Up @@ -320,7 +348,11 @@ class _AnimateState extends State<Animate> with SingleTickerProviderStateMixin {
for (EffectEntry entry in widget._entries) {
child = entry.effect.build(context, child, _controller, entry);
}
return reparent?.call(parent, child) ?? child;
Widget animate = reparent?.call(parent, child) ?? child;
if (widget.useRepaintBoundary ?? Animate.defaultUseRepaintBoundary) {
animate = RepaintBoundary(child: animate);
}
return animate;
}
}

Expand All @@ -336,6 +368,7 @@ extension AnimateWidgetExtensions on Widget {
AnimationController? controller,
Adapter? adapter,
double? target,
bool? useRepaintBoundary,
}) =>
Animate(
key: key,
Expand All @@ -346,6 +379,7 @@ extension AnimateWidgetExtensions on Widget {
controller: controller,
adapter: adapter,
target: target,
useRepaintBoundary: useRepaintBoundary,
child: this,
);
}
Expand Down