build method

Path build(
  1. Size parentSize, {
  2. Size? size,
  3. Matrix4? transform,
  4. AlignmentGeometry? origin = Alignment.center,
  5. AlignmentGeometry alignment = Alignment.center,
  6. Offset? offset,
  7. Offset? translate,
  8. double? margin,
})

Implementation

Path build(
  Size parentSize, {
  Size? size,
  Matrix4? transform,
  AlignmentGeometry? origin = Alignment.center,
  AlignmentGeometry alignment = Alignment.center,
  Offset? offset,
  Offset? translate,
  double? margin,
}) {
  // assert that translate is >= -1 and <= 1
  assert(translate == null || (translate.dx >= -1 && translate.dx <= 1), 'translate.dx must be >= -1 and <= 1');
  final Matrix4 result = Matrix4.identity();
  var opath = path(size ?? parentSize);
  var bounds = opath.getBounds();
  if (size != null) {
    result.scale(size.width / bounds.width, size.height / bounds.height);
    bounds = Rect.fromLTWH(
      bounds.left,
      bounds.top,
      size.width,
      size.height,
    );
  }

  // if bounds.topLeft is not zero then we need to translate the shape
  // to the origin
  if (bounds.topLeft != Offset.zero) {
    opath = opath.shift(-bounds.topLeft);
  }

  // in alingment its bit different than origin
  // because we need to translate the shape to the center or corner
  // depending on the alignment
  // we have all needed data in the bounds
  // also we have the parentSize
  // so we can calculate the offset
  final Alignment resolvedAlignment = alignment.resolve(null);
  final Offset resolvedAlignmentOffset = resolvedAlignment.alongSize(parentSize);
  final Offset resolvedBoundsOffset = resolvedAlignment.alongSize(bounds.size);

  result.translate(
    resolvedAlignmentOffset.dx - resolvedBoundsOffset.dx,
    resolvedAlignmentOffset.dy - resolvedBoundsOffset.dy,
  );

  if (translate != null) {
    result.translate(translate.dx * parentSize.width, translate.dy * parentSize.height);
  }

  // if transform is provided use it and apply origin to it
  if (transform != null) {
    Offset? _origin;
    if (origin != null) {
      _origin = origin.resolve(null).alongOffset(
            Offset(
              bounds.width,
              bounds.height,
            ),
          );
      result.translate(_origin.dx, _origin.dy);
    }
    result.multiply(transform);
    if (origin != null) {
      result.translate(-_origin!.dx, -_origin.dy);
    }
  }

  // if margin is provided use it to apply scale transform
  // if (margin != null) {
  //   // var vw = (bounds.width + margin*2) / bounds.width;
  //   // var vh = (bounds.height + margin*2) / bounds.height;
  //   result.scale(1.0, 1.0);
  //   // re align the shape
  //   result.translate(
  //     -margin,
  //     -0.0,
  //   );
  // }

  if (margin != null) {
    var offset = Offset(margin * bounds.width / 2, margin * bounds.height / 2);
    // scale
    opath = opath.transform(Matrix4.diagonal3Values(margin, margin, 2).storage);
    opath = opath.shift(-offset + Offset(bounds.width / 2, bounds.height / 2));
  }

  // offset is the last thing to apply
  if (offset != null) {
    result.translate(offset.dx, offset.dy);
  }

  return opath.transform(result.storage);
}