getFollowerOffset method

  1. @override
Offset getFollowerOffset({
  1. required Size followerSize,
  2. required Size targetSize,
  3. required Rect theaterRect,
})
override

Returns the offset at which to position the follower element in relation to the top left of the targetSize.

The followerSize is the final size of the follower element after layout For example, if it is used in portals, it is based on the follower constraints determined by Anchor.getFollowerConstraints.

The targetSize represents the bounds of the element which the follower element should be anchored to. If it is used in portals, this must be the same value that is passed to Anchor.getFollowerConstraints.

The theaterRect represents the bounds of the full available space to place the follower element in. Note that this is also relative to the top left of the targetSize. This means that every offset going into or coming out of this function is relative to the top-left corner of the target.

Example

In this example, our follower element has a size of Size(30, 30) and should be anchored to the bottom right of the target.

If we assume the full available space starts at absolute (0, 0) and spans to absolute (100, 100) and the target rect starts at absolute (40, 40) and spans to absolute (60, 60), the passed values will be:

  • Rect.fromLTWH(0, 0, 20, 20) for the targetSize.
  • Rect.fromLTWH(-40, -40, 100, 100) for the theaterRect.
  • Size(30, 30) for the followerSize.
  • Offset(20, 20) as the return value.

Implementation

@override
Offset getFollowerOffset({
  required Size followerSize,
  required Size targetSize,
  required Rect theaterRect,
}) {
  final followerAlignPortal = followerSize.alignedTo(
    theaterRect.size,
    followerAlignment: follower,
    targetAlignment: portal,
    offset: theaterRect.topLeft + offset,
  );
  final followerAlignTarget = followerSize.alignedTo(
    targetSize,
    followerAlignment: follower,
    targetAlignment: target,
    offset: offset,
  );

  final followerRectBeforeClamp = Rect.fromLTWH(
    alignToPortal.x ? followerAlignPortal.left : followerAlignTarget.left,
    alignToPortal.y ? followerAlignPortal.top : followerAlignTarget.top,
    alignToPortal.x ? followerAlignPortal.width : followerAlignTarget.width,
    alignToPortal.y ? followerAlignPortal.height : followerAlignTarget.height,
  );

  final followerRect = followerRectBeforeClamp.shiftToWithinBound(
      theaterRect, shiftToWithinBound);

  // print('hi getFollowerOffset '
  //     'followerSize=$followerSize targetSize=$targetSize theaterRect=$theaterRect '
  //     'followerAlignPortal=$followerAlignPortal followerAlignTarget=$followerAlignTarget '
  //     'followerRect=$followerRect');

  if (!theaterRect.fullyContains(followerRect)) {
    final backup = this.backup;
    if (backup != null) {
      return backup.getFollowerOffset(
        followerSize: followerSize,
        targetSize: targetSize,
        theaterRect: theaterRect,
      );
    }
  }

  return followerRect.topLeft;
}