zathras / jovial_svg

Flutter library for robust, efficient rendering of SVG static images
BSD 3-Clause "New" or "Revised" License
100 stars 20 forks source link

[Feature requests] Crossfade the asset/network image after loading #70

Closed milindgoel15 closed 11 months ago

milindgoel15 commented 1 year ago

Hi,

I am using the avd assets to display in my flutter app. While they work great, i would appreciate if we could have a feature that will crossfade the between onLoading, si and/or onError widgets. Since currently the images show up instantly without an animation.

thanks

billf-pshs commented 1 year ago

I assume this is for ScalableImageWidget.

Looking through what Flutter provides, https://api.flutter.dev/flutter/widgets/AnimatedCrossFade-class.html looks like a good candidate to model the API after. It looks like it would be sufficient to add the following to the constructor:

Duration crossFadeDuration = const Duration(seconds: 0);
Curve crossFadeCurve = Curves.linear
zathras commented 1 year ago

Let me know what you think of the switcher arg to the widget, in 1.1.18--rc.1. It's used like this:

              child: ScalableImageWidget.fromSISource(
                  cache: _svgCache,
                  scale: 1000,
                  si: ScalableImageSource.fromSvgHttpUrl(widget.svgs[index]),
                  onLoading: _onLoading,
                  onError: _onError,
                  switcher: _switcher),
            );
          }),
    );
  }

  Widget _onLoading(BuildContext context) => Container(
      key: const ValueKey(1), color: Colors.green, width: 500, height: 500);
  Widget _onError(BuildContext context) =>
      Container(key: const ValueKey(2), color: Colors.red);
  Widget _switcher(BuildContext context, Widget child) => AnimatedSwitcher(
      child: child, duration: const Duration(milliseconds: 250));
zathras commented 1 year ago

https://github.com/zathras/jovial_svg/commit/3a5546a9b97c759ed7fdff7a1670ef45012f2866

milindgoel15 commented 1 year ago

I just tried it using this code:

Widget _switcher(BuildContext context, Widget child) => AnimatedSwitcher(
      switchInCurve: Curves.easeIn,
      duration: const Duration(milliseconds: 500),
      transitionBuilder: (child, animation) {
        return FadeTransition(
          opacity: animation,
          child: child,
        );
      },
      child: child,
    );

It works great as expected but can we make that animation play only once similar to how cached_network_image does? Say you have 2 pages, so the animation will start over when changing between those 2 pages using say bottom navigation bar.

Also, the default curves could be changed to easein and easeout.

While I also have another thing in my mind, not relating to this feature request. The scalable image widget from any source only supports scale param. Could there also be height and width that can be used instead of scale? maybe as a different widget?

zathras commented 1 year ago

t works great as expected but can we make that animation play only once similar to how cached_network_image does? Say you have 2 pages, so the animation will start over when changing between those 2 pages using say bottom navigation bar.

It sounds like you need to set the key parameter of the ScalableImageWidget. I believe you'd need to use a GlobalKey, since you're talking about two different pages. It's the standard mechanism for when you need to maintain state in a Flutter widget between screens.

Also, it sounds like you're actually reloading the image when you switch screens. Using a GlobalKey should avoid that, too. So should having an adequately large cache.

Also, the default curves could be changed to easein and easeout.

That's determined by AnimatedSwitcher, which is part of Google's standard Flutter library.

While I also have another thing in my mind, not relating to this feature request. The scalable image widget from any source only supports scale param. Could there also be height and width that can be used instead of scale? maybe as a different widget?

It shouldn't be hard to get what you want with an appropriate BoxFit, and a containing widget that sets the width and height (which is probably called something like Box or FixedSizeBox in the standard Flutter library).

milindgoel15 commented 1 year ago

It sounds like you need to set the key parameter of the ScalableImageWidget. I believe you'd need to use a GlobalKey, since you're talking about two different pages. It's the standard mechanism for when you need to maintain state in a Flutter widget between screens.

Is it not possible without defining any key? I also use cached_network_image and it doesn't require any need for a key and allows for fading between placeholders, error, image widget out of the box without requiring to make a switcher widget.

That's determined by AnimatedSwitcher, which is part of Google's standard Flutter library.

oh yea completely forgot about it. nvm

It shouldn't be hard to get what you want with an appropriate BoxFit, and a containing widget that sets the width and height (which is probably called something like Box or FixedSizeBox in the standard Flutter library).

Sizedbox yea but it will be like an extra parent.

zathras commented 1 year ago

Is it not possible without defining any key?

Sure, by giving it an adequately-sized cache. See ScalableImageCache.

I also use cached_network_image and it doesn't require any need for a key and allows for fading between placeholders, error, image widget out of the box without requiring to make a switcher widget.

I haven't looked at that in detail, but I bet they're using a decent-sized cache behind your back. And, that cache might rely on non-public APIs to work reliably when there's memory pressure. That's what's behind the "NOTE" text at https://pub.dev/documentation/jovial_svg/1.1.18-rc.1/jovial_svg/ScalableImageWidget/ScalableImageWidget.fromSISource.html

It shouldn't be hard to get what you want with an appropriate BoxFit, and a containing widget that sets the width and height (which is probably called something like Box or FixedSizeBox in the standard Flutter library).

Sizedbox yea but it will be like an extra parent.

And? Composing widgets like this is common, and downright encouraged in Flutter. Sure, I could reinvent this particular wheel, but there's no real reason to -- any extra memory or time overhead is completely trivial. The sized box widget exists precisely for cases like this.

milindgoel15 commented 1 year ago

How much size is the ideal size for this? I load up all the svgs from local assets.

zathras commented 1 year ago

How much size is the ideal size for this?

That depends on your application -- the number of images displayed at one time, the size of the image, how much free memory you expect to have, etc. If there were one ideal size for everybody, I'd make that the default.

milindgoel15 commented 1 year ago

Understandable

milindgoel15 commented 11 months ago

so can be closed now ig since 1.1.18 is released