bluefireteam / photo_view

📸 Easy to use yet very customizable zoomable image widget for Flutter, Photo View provides a gesture sensitive zoomable widget. Photo View is largely used to show interacive images and other stuff such as SVG.
MIT License
1.9k stars 544 forks source link

Rounded corners #419

Open bartekpacia opened 3 years ago

bartekpacia commented 3 years ago

Is your feature request related to a problem? Please describe. I can't find a way to gracefully handle an image with rounded corners (by wrapping the image with ClipRRect). It really messes up the Hero animation experience.

https://user-images.githubusercontent.com/40357511/118408191-babfc380-b684-11eb-8041-dba3eb14f294.mov

Describe the solution you'd like I'd like to be able to somehow apply rounded corners to the image (and also, to preserve and/or animate those corners during the hero flight animation).

renancaraujo commented 3 years ago

You can use the custom child constructor on photo view, and wrap the image with a ClipRRect widget with border-radius set to BorderRadius.zero.

bartekpacia commented 3 years ago

Thank you @renancaraujo, I didn't know about the custom child constructor. I did what you suggested, but the problem persists:

https://user-images.githubusercontent.com/40357511/119065903-e4f3e700-b9de-11eb-8fea-41d77707189c.mov

small image screen code

Hero(
  tag: place.images[i],
  child: Container(
    width: 320,
    height: 240,
    child: ClipRRect(
      borderRadius: BorderRadius.circular(16),
      child: GestureDetector(
        onTap: () {
          Navigator.of(context).push(
            PageRouteBuilder(
              opaque: false,
              pageBuilder: (context, animation, secondaryAnimation) =>
                  FilePhotoScreen(
                images: place.images,
                initialImage: i,
              ),
              transitionsBuilder: (context, animation,
                      secondaryAnimation, child) =>
                  FadeTransition(opacity: animation, child: child),
              transitionDuration: const Duration(milliseconds: 500),
            ),
          );
        },
        child: Image.file(
          place.images[i].getImage(datafilePath: datafilePath),
          fit: BoxFit.cover,
        ),
      ),
    ),
  ),
  ),

enlarged image screen code

PhotoViewGallery.builder(
    builder: (BuildContext context, int index) {
      return PhotoViewGalleryPageOptions.customChild(
        child: ClipRRect(
          borderRadius: BorderRadius.zero,
          child: PhotoView(
            imageProvider:
                FileImage(widget.images[index].getImage(datafilePath: datafilePath)),
            heroAttributes: PhotoViewHeroAttributes(tag: widget.images[index]),
          ),
        ),
      );
    },
    itemCount: widget.images.length,
    loadingBuilder: (context, event) => Center(
      child: Container(
        width: 20.0,
        height: 20.0,
        child: CustomProgressIndicator(),
      ),
    ),
    pageController: pageController,
  ),
renancaraujo commented 3 years ago

By doing that, you should put the a hero widget around cliprrrect in the small image screen

bartekpacia commented 3 years ago

hi @renancaraujo, thanks for helping me:)

I did (or I think I did) what you said but I still can't make it work:c

you should put the a hero widget around cliprrrect in the small image screen

I did this, code:

Hero(
  tag: place.images[i],
  child: ClipRRect(
    borderRadius: BorderRadius.circular(16),
    child: GestureDetector(
      onTap: () {
        Navigator.of(context).push(
          PageRouteBuilder(
            opaque: false,
            pageBuilder: (context, animation, secondaryAnimation) =>
                FileImageScreen(
              images: place.images,
              startAt: i,
            ),
            transitionsBuilder:
                (context, animation, secondaryAnimation, child) =>
                    FadeTransition(opacity: animation, child: child),
            transitionDuration: const Duration(milliseconds: 500),
          ),
        );
      },
      child: Image.file(
        place.images[i].getImage(datafilePath: datafilePath),
        fit: BoxFit.cover,
      ),
    ),
  ),
),

I'm still getting the same result as on the gif somewhere above