“This is the 12th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

preface

We switch to animation in the page, hero rescue is more interesting! Hero animation was introduced, and using Hero for transitions is a great experience. In this article, we’ll explore the return effects of the Hero animation.

The definition of a Hero

The Hero component is a StatefulWidget constructed as follows:

const Hero({
  Key? key,
  required this.tag,
  this.createRectTween,
  this.flightShuttleBuilder,
  this.placeholderBuilder,
  this.transitionOnUserGestures = false.required this.child,
})
Copy the code

CreateRectTween is a rectangular interpolation that controls the path of the Hero component. In fact, like normal animation, there is a time curve between 0 and 1.0, and then createRectTween ensures that the Hero component reaches the specified position and size of the rectangle before and after the animation. Here’s a caption from the official website:

RectTween

RectTween is similar to Tween, but it’s actually how the matrix changes during the animation. Let’s look at the definition of RectTween:

class RectTween extends Tween<Rect? >{
  RectTween({ Rect? begin, Rect? end }) : super(begin: begin, end: end);

  /// Builds a new interpolation rectangle with the given animation time value
  @override
  Rect? lerp(double t) => Rect.lerp(begin, end, t);
}
Copy the code

This class is very simple. It simply calls rect. lerp at each animation point in time to build an interpolated rectangle. The rect. lerp method is as follows:

static Rect? lerp(Rect? a, Rect? b, double t) {
    assert(t ! =null);
    if (b == null) {
      if (a == null) {
        return null;
      } else {
        final double k = 1.0 - t;
        returnRect.fromLTRB(a.left * k, a.top * k, a.right * k, a.bottom * k); }}else {
      if (a == null) {
        return Rect.fromLTRB(b.left * t, b.top * t, b.right * t, b.bottom * t);
      } else {
        returnRect.fromLTRB( _lerpDouble(a.left, b.left, t), _lerpDouble(a.top, b.top, t), _lerpDouble(a.right, b.right, t), _lerpDouble(a.bottom, b.bottom, t), ); }}}Copy the code

If neither rectangle A nor rectangle B is empty, a new rectangle defined by a fixed point is returned. The key here is the _lerpDouble method, which ultimately does the vertices move based on the animation time.

double? lerpDouble(num? a, num? b, double t) {
  /// .
  return a * (1.0 - t) + b * t;
}
Copy the code

The transition between the two rectangles is completed by moving from the vertex of rectangle A to the vertex of rectangle B. With this foundation we can build our custom RectTween. And the animation curve we talked about before (animation curve used every day, can you make your own? You will after reading this article! It’s similar.

Custom RectTween

So let’s do a custom RectTween, and make sure that we start at rectangle A, we end at rectangle B, and then we just move it along the curve. Below is a custom RectTween obtained by converting time using a curve. After the curve transformation, the transformT value is 0 to 1.0, and the _rectMove method is used to transition from the beginning rectangle to the end rectangle.

class CustomRectTween extends RectTween {
  final Rect begin;
  final Rect end;

  CustomRectTween({required this.begin, required this.end})
      : super(begin: begin, end: end);

  @override
  Rect lerp(double t) {
    double transformT = Curves.easeInOutBack.transform(t);

    var rect = Rect.fromLTRB(
        _rectMove(begin.left, end.left, transformT),
        _rectMove(begin.top, end.top, transformT),
        _rectMove(end.right, end.right, transformT),
        _rectMove(begin.bottom, end.bottom, transformT));

    return rect;
  }

  double _rectMove(double begin, double end, double t) {
    return begin * (1- t) + end * t; }}Copy the code

Running effect

You can see that at the end, there’s a rebound effect because of the Curves. EaseInOutBack. Source code has been uploaded to: animation related source code.

conclusion

This article describes how the Hero animation component’s createRectTween property animates custom path effects. In practice, you can build some interesting paths according to your own needs to improve user experience or add fun.

I am dao Code Farmer with the same name as my wechat official account. This is a column about the introduction and practice of Flutter, providing systematic learning articles about Flutter. See the corresponding source code here: The source code of Flutter Introduction and Practical column. If you have any questions, please add me to the wechat account: island-coder.

👍🏻 : feel the harvest please point a praise to encourage!

🌟 : Collect articles, easy to look back!

💬 : Comment exchange, mutual progress!