skip to Main Content

I have the following design. How can I implement it in Flutter? I tried using a stack with the image at the bottom and a frame on top using a .png, but I don’t think that’s the best solution. Is there a better approach?

enter image description here

2

Answers


  1. the appropriate approach would be to apply a CustomClipper.

    Here is an article to explain the topic : https://medium.com/flutter-community/flutter-custom-clipper-28c6d380fdd6

    So you have to create your custom class that extends the CustomClipper.

    Example (that doesn’t suit your case) :

    class MyCustomClipper extends CustomClipper<Path> {
      @override
      Path getClip(Size size) {
        final path = Path()
          ..lineTo(0.0, size.height)
          ..lineTo(size.width, size.height)
          ..lineTo(size.width, 0.0)
          ..quadraticBezierTo(size.width, 0.0, size.width - 20.0, 0.0)
          ..lineTo(40.0, 70.0)
          ..quadraticBezierTo(10.0, 85.0, 0.0, 120.0)
          ..close();
        return path;
      }
    
      @override
      bool shouldReclip(CustomClipper<Path> oldClipper) {
        return true;
      }
    }
    

    This code comes from the flutter_custom_clippers (you can find some cool example in here).

    Then you can use it on your image as follow :

     ClipPath(
            clipper: MyCustomClipper(),
            child: MyImageWidget(),
            ),
          )
    

    Now all you have to do is discover the possibility of CustomClipper and create the class that match your case.

    Login or Signup to reply.
  2. In order to achieve that, you must use a CustomClipper, check this code

    class ImageClipper extends CustomClipper<Path> {
      final double radius;
    
      ImageClipper({
        this.radius = 80,
      });
    
      @override
      Path getClip(Size size) {
        final leftHeight = size.height * 0.9;
    
        return Path()
          ..moveTo(0.0, radius)
          ..lineTo(0.0, size.height - radius)
          // Bottom Left
          ..quadraticBezierTo(
            0.0,
            size.height,
            radius,
            size.height,
          )
          ..lineTo(size.width - radius, leftHeight)
          // Bottom Right
          ..quadraticBezierTo(
            size.width,
            leftHeight - 4,
            size.width,
            leftHeight - radius,
          )
          ..lineTo(size.width, 0.0 + radius)
          // Top Right
          ..quadraticBezierTo(
            size.width,
            0.0,
            size.width - radius,
            0.0,
          )
          ..lineTo(0.0 + radius, 0.0)
          // Top Left
          ..quadraticBezierTo(
            0.0,
            0.0,
            0.0,
            radius,
          )
          ..close();
      }
    
      @override
      bool shouldReclip(covariant CustomClipper<Path> oldClipper) => true;
    }
    

    and here is an example of how to use it

    import 'package:flutter/material.dart';
    
    const imageUrl =
        'https://images.pexels.com/photos/268533/pexels-photo-268533.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500';
    
    class TempPage extends StatelessWidget {
      const TempPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.amber,
          appBar: AppBar(
            title: const Text('Image clipped'),
          ),
          body: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Image.network(
                imageUrl,
                height: 300,
                width: 200,
                fit: BoxFit.fill,
              ),
              ClipPath(
                clipper: ImageClipper(
                  radius: 20,
                ),
                child: Image.network(
                  imageUrl,
                  height: 300,
                  width: 200,
                  fit: BoxFit.fill,
                ),
              ),
            ],
          ),
        );
      }
    }
    

    remember to change shouldReclip to false if needed

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search