getLayoutTransformTo function

Offset getLayoutTransformTo(
  1. RenderObject current,
  2. RenderObject ancestor, {
  3. bool excludeScrollOffset = false,
})

Implementation

Offset getLayoutTransformTo(RenderObject current, RenderObject ancestor, {bool excludeScrollOffset = false}) {
  final List<RenderObject> renderers = <RenderObject>[];
  for (RenderObject renderer = current; renderer != ancestor; renderer = renderer.parent!) {
    renderers.add(renderer);
    assert(renderer.parent != null);
  }
  renderers.add(ancestor);
  List<Offset> stackOffsets = [];
  final Matrix4 transform = Matrix4.identity();

  for (int index = renderers.length - 1; index > 0; index -= 1) {
    RenderObject parentRenderer = renderers[index];
    RenderObject childRenderer = renderers[index - 1];
    // Apply the layout transform for renderBoxModel and fallback to paint transform for other renderObject type.
    if (parentRenderer is RenderBoxModel) {
      // If the next renderBox has a fixed position,
      // the outside scroll offset won't affect the actual results because of its fixed positioning.
      if (childRenderer is RenderBoxModel && childRenderer.renderStyle.position == CSSPositionType.fixed) {
        stackOffsets.clear();
      }

      stackOffsets.add(parentRenderer.obtainLayoutTransform(childRenderer, excludeScrollOffset));
    } else if (parentRenderer is RenderSliverRepaintProxy) {
      parentRenderer.applyLayoutTransform(childRenderer, transform, excludeScrollOffset);
    } else if (parentRenderer is RenderBox) {
      assert(childRenderer.parent == parentRenderer);
      if (childRenderer.parentData is BoxParentData) {
        stackOffsets.add((childRenderer.parentData as BoxParentData).offset);
      }
    }
  }

  if (stackOffsets.isEmpty) return Offset.zero;

  return stackOffsets.reduce((prev, next) => prev + next);
}