Home > OS >  Shaping Container using Bezier Curve in Flutter
Shaping Container using Bezier Curve in Flutter

Time:02-04

Up to this point, I wasn't aware that we could make shapes of our choices in Flutter and hence I'm totally new to this. I would like to shape my container to resemble the below design but I am totally short of ideas as to how this can be done. I did a bit of reading to find out about the concepts of the Bezier Curve but upon trying to apply that knowledge to the container below, I ended up getting something pretty horrendous. The screenshots and the code are as follows:

enter image description here

This is what I ended up getting:

enter image description here

class ProfilePage extends StatefulWidget {
  ProfilePageState createState() => ProfilePageState();
}

class ProfilePageState extends State<ProfilePage> {
  @override
  Widget build(BuildContext context) {
    final height = MediaQuery.of(context).size.height;
    final width = MediaQuery.of(context).size.width;

    // TODO: implement build
    return Scaffold(
      body: Container(
        height: height * 1,
        width: width * 1,
        color: Colors.red,
        child: Column(
          children: [
            Stack(
              children: [
                ClipPath(
                  clipper: CurvedAppBar(),
                  child: Container(
                    height: height * 0.2,
                    width: double.infinity,
                    color: Colors.white,
                  ),
                ),
                Positioned(child: Image.asset('assets/images/logo-with-bg.png'))
              ],
            )
          ],
        ),
      ),
    );
  }
}



import 'package:flutter/material.dart';
    
    class CurvedAppBar extends CustomClipper<Path> {
      @override
      Path getClip(Size size) {
        var path = Path();
        path.lineTo(0, size.height);
        var firstStart = Offset(size.width / 5, size.height);
        var firstEnd = Offset(size.width / 2.25, size.height - 50);
        path.quadraticBezierTo(
            firstStart.dx, firstEnd.dy, firstEnd.dx, firstEnd.dy);
    
        var secondStart =
            Offset(size.width - (size.width / 3.24), size.height - 105);
        var secondEnd = Offset(size.width, size.height - 10);
        path.quadraticBezierTo(
            secondStart.dx, secondStart.dy, secondEnd.dx, secondEnd.dy);
        path.lineTo(size.width, 0);
    
        path.close();
        return path;
      }
    
      @override
      bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
        // TODO: implement shouldReclip
        return false;
      }
    }

Any ideas how this can be shaped?

CodePudding user response:

Check this out:

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: Center(
          child: Container(
            color: Colors.grey,
            child: ClipPath(
              clipper: Clipp(),
              child: Container(
                width: 500,
                height: 500,
                color: Colors.pink,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class Clipp extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    Path path = Path();
    path.moveTo(150, 0);
    path.quadraticBezierTo(120, 150, 0, 150);
    path.lineTo(0, 380);
    path.quadraticBezierTo(size.width / 4, size.height, size.width, 270);
    path.lineTo(size.width, 0);
    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => true;
}

The output: enter image description here

Edit: To make it dynamic, try this:

class Clipp extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    Path path = Path();
    double firstFactor = size.width / 3.3333;
    double secondFactor = size.height / 2;
    double thirdFactor = size.width / 4.166;
    double fourthFactor = size.height / 1.4285;
    path.moveTo(firstFactor, 0);
    path.quadraticBezierTo(thirdFactor, firstFactor, 0, firstFactor);
    path.lineTo(0, fourthFactor);
    path.quadraticBezierTo(
      size.width / 3,
      size.height,
      size.width,
      secondFactor,
    );
    path.lineTo(size.width, 0);
    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => true;
}
  •  Tags:  
  • Related