dnfield / flutter_svg

SVG parsing, rendering, and widget library for Flutter
MIT License
1.67k stars 459 forks source link

Resize of widget in constrained conditions not working as expected #759

Open matecode opened 2 years ago

matecode commented 2 years ago

I want the SvgPicture widget to automatically resize its height.

Here is a code example:

The starting code is a an easy example of an SvgPicture with the original width an height of the svg image. To see better what happens there is a red background on the container.

Container(
          color: Colors.red,
          child: IntrinsicHeight(
            child: SvgPicture.asset(
              Assets.diningplan.images.basket.path,
              fit: BoxFit.scaleDown,
            ),
          ),
        ),

results to image

if i add constraints: BoxConstraints(maxWidth: 20), to the container, the result is: image

I would expect that SvgImage resize its own height.

gabrielgarciagava commented 2 years ago

I have faced the same issue recently. I've created a simple project to show the issue, and I also have a suggestion of how to fix.

Example: https://github.com/gabrielgarciagava/flutter_svg_aspect_ratio_issue Snippet:

class ImageVsSvgPicture extends StatelessWidget {
  const ImageVsSvgPicture({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          color: Colors.green,
          child: Image.asset("images/cube.png"),
        ),
        Container(
          color: Colors.red,
          child: SvgPicture.asset("images/logo.svg"),
        ),
      ],
    );
  }
}
Screenshot 2022-08-29 at 12 23 01

Image and SvgPitcure behaves differently. SvgPicture behaves as the issue you described. Image behaves as you expected.

The issue is caused by this part of the code:

double? width = widget.width;
double? height = widget.height;
if (width == null && height == null) {
  width = viewport.width;
  height = viewport.height;
} else if (height != null) {
  width = height / viewport.height * viewport.width;
} else if (width != null) {
  height = width / viewport.width * viewport.height;
}

In case width and height are not defined, the image is forced to have the dimensions specified by the svg file. This code was injected to deal with this issue: https://github.com/dnfield/flutter_svg/issues/57#

I suggest using AspectRatio widget instead of setting the width and height.

gabrielgarciagava commented 2 years ago

The code I wrote on my fork fixed the problem that I was facing. https://github.com/dnfield/flutter_svg/compare/master...gabrielgarciagava:flutter_svg:master

I did not create a PR because I'm not confident if this is correct. All tests are passing though. I should also probably write a test to describe the behavior we expect.

@matecode You can test my fork of the project if you want. Let me know if it works for you.

Lilian-C commented 1 year ago

I am still able to reproduce this error in the latest flutter_svg version (2.0.8).

Are there any fixes coming up soon, or is there any workaround to avoid this problem?