Create this shape using ClipPath CustomClipper - flutter

I'm trying to clip a widget using ClipPath CustomClipper -> so far I was able to recreate a wave shape
ClipPath(
clipper: WaveClipper(),
child: CustomWidget(),
);
class WaveClipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
var path = new Path();
path.lineTo(
0, size.height);
var firstStart = Offset(size.width / 5, size.height);
var firstEnd = Offset(size.width / 2.25, size.height - 50.0);
path.quadraticBezierTo(
firstStart.dx, firstStart.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(CustomClipper<Path> oldClipper) {
return false; //if new instance have different instance than old instance
//then you must return true;
}
but what I would need to achieve is this pink shape shown on this image :
the top part does not need to be clipped as it's the edge of the screen, only the bottom

Maybe it's not exactly how you want it, but with small adjustments it stays the same, you have to pay attention to where you left off to start correctly
class CustomClipperImage extends CustomClipper<Path> {
#override
bool shouldReclip(CustomClipper oldClipper) {
return false;
}
#override
getClip(Size size) {
var path = Path();
path.lineTo(0, size.height-70);
path.quadraticBezierTo(0, size.height+40,size.width-40, size.height-
130);
path.quadraticBezierTo(size.width+60, size.height-170,size.width, 0);
path.close();
return path;
}
}

Did you see flutter_custom_clippers package? I think its source code will be helpfull.

Related

Flutter - How to clip an arc container?

How to implement effect like pic below.
I have a rect container(width:400, height:100), I want to clip the blue area of the rect, so I can get the orange area.Attention,
The orange arc is tangent to the bottom line . Could you give the details code?
You can use a Custom Clipper class , to get this type of shape I will share an example code you can change values according to your need
class ClipPathClass extends CustomClipper<Path> {
#override
Path getClip(Size size) {
double radius = 50;
var path = Path();
path.lineTo(0.0, size.height - 30);
var firstControlPoint = Offset(size.width / 4, size.height);
var firstPoint = Offset(size.width / 2, size.height);
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
firstPoint.dx, firstPoint.dy);
var secondControlPoint = Offset(size.width - (size.width / 4), size.height);
var secondPoint = Offset(size.width, size.height - 30);
path.quadraticBezierTo(secondControlPoint.dx, secondControlPoint.dy,
secondPoint.dx, secondPoint.dy);
path.lineTo(size.width, 0.0);
path.lineTo(size.width - radius, 0);
path.close();
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
then use this ClipPathClass() like ,
ClipPath(
clipper: ClipPathClass(),
child: Container(width:400,height: 100,color:Colors.grey)
)

Flutter CustomClipper Triangle

I have this triangle
and a i would like that its shape would be like this
Can someone help me ?
this is my actual code
class TriangleClipperr extends CustomClipper<Path> {
#override
Path getClip(Size size) {
final path = Path();
path.lineTo(size.width, 0.0);
path.lineTo(size.width / 2, size.height);
path.close();
return path;
}
#override
bool shouldReclip(TriangleClipperr oldClipper) => false;
}
First, you need to move the current point to middle, then draw rest path.
class TriangleClipperr extends CustomClipper<Path> {
#override
Path getClip(Size size) {
final path = Path();
path.moveTo(size.width / 2, 0);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
path.close();
return path;
}
#override
bool shouldReclip(TriangleClipperr oldClipper) => false;
}
Shape depends on parent size.

Custom clip path appbar flutter

I want to create custom appbar shape as shown in below image. How we can do such shape using clippath?
Tried code:
class CustomAppBarShape extends CustomClipper<Path> {
#override
getClip(Size size) {
double height = size.height;
double width = size.width;
var path = Path();
path.lineTo(0, size.height);
path.arcToPoint(Offset(size.width, size.height),
radius: Radius.elliptical(30, 10),
);
path.lineTo(size.width, 0);
path.close();
return path;
}
#override
bool shouldReclip(CustomClipper oldClipper) {
return true;
}
}
I created the desired AppBar shape by giving custom shape to the AppBar border, check out the live example here.
If you want to clip the AppBar you can use similar Path in the clipper too but I think giving custom shape to the border is better.
code for custom AppBar border shape:
class CustomAppBarShape extends ContinuousRectangleBorder {
#override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
double height = rect.height;
double width = rect.width;
var path = Path();
path.lineTo(0, height + width * 0.1);
path.arcToPoint(Offset(width * 0.1, height),
radius: Radius.circular(width * 0.1),
);
path.lineTo(width * 0.9, height);
path.arcToPoint(Offset(width, height + width * 0.1),
radius: Radius.circular(width * 0.1),
);
path.lineTo(width, 0);
path.close();
return path;
}
}
Edit:
For dynamic edge radius update the customAppBarShape with the multiplier multi as constructor argument, and use multi to create outer path.
class CustomAppBarShape extends ContinuousRectangleBorder {
final double multi;
const CustomAppBarShape({this.multi = 0.1});
#override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
double height = rect.height;
double width = rect.width;
var path = Path();
path.lineTo(0, height + width * multi);
path.arcToPoint(Offset(width * multi, height),
radius: Radius.circular(width * multi),
);
path.lineTo(width * (1 - multi), height);
path.arcToPoint(Offset(width, height + width * multi),
radius: Radius.circular(width * multi),
);
path.lineTo(width, 0);
path.close();
return path;
}
}
Then send your desired value in constructor parameter like so,
appBar: AppBar(
title: Text(widget.title),
shape: const CustomAppBarShape(multi: 0.02),
)
make sure the value of multi is less than 1 for desired shape.
if you still prefer to use clipper instead of custom shape, you can use my code below for clip image.
class BannerClipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
var height = size.height;
var width = size.width;
double radius = 20;
Path path = Path()
..lineTo(0, height)
..arcToPoint(Offset(20, height - 20), radius: Radius.circular(radius))
..lineTo(width - 20, height - 20)
..arcToPoint(Offset(width, height), radius: Radius.circular(radius))
..lineTo(width, 0)
..close();
return path;
}
#override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

How can I achieve an inclined looking path in flutter (taking this picture as example)

Path I am trying to achieve
I had been trying to achieve this path, but I am having trouble when clipping, not only it clips the opposite part of the container but also gets my path to be dirty.
I am also looking on achieving the same effect, but with an opposite direction.
This is the code i have done so far(It is an up arc clip path):
class UpArcClip extends CustomClipper<Path> {
#override
Path getClip(Size size) {
final path = Path();
path.lineTo(0, size.height);
path.lineTo(0.0, size.height - 100);
path.quadraticBezierTo(
size.width / 2, size.height, size.width, size.height - 100);
path.lineTo(size.width, 0.0);
path.close();
return path;
}
#override
bool shouldReclip(CustomClipper old) => false;
}
Already achieved it by myself:
class LeftInclinedArcClipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
final path = Path();
path.moveTo(0, size.height);
path.lineTo(0, size.height * 0.7);
path.quadraticBezierTo(
size.width / 3, size.height * 0.45, size.width, size.height * 0.53);
path.lineTo(size.width, size.height);
path.close();
return path;
}
#override
bool shouldReclip(CustomClipper old) => false;
}

How to make multiple pointed edge at the left side using CustomClipper?

I am trying to make multiple pointed edge at the left side.
class CustomClipPath extends CustomClipper<Path> {
#override
Path getClip(Size size) {
Path path = Path();
path.lineTo(size.width, 0.0);
var curYPos = 0.0;
var curXPos = size.width;
var increment = size.height / 30;
while (curYPos < size.height) {
curYPos += increment;
curXPos = curXPos == size.width ? size.width - 8 : size.width;
path.lineTo(curXPos, curYPos);
}
path.lineTo(0, size.height);
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
However, instead of multiple pointed edge on the left side, i got multiple pointed edge on the right side like image below:
Text
Here's a clipper that is using left side of the child.
class CustomClipPath extends CustomClipper<Path> {
#override
Path getClip(Size size) {
Path path = Path();
var curYPos = 0.0;
var curXPos = 0.0;
var increment = size.height / 30;
while (curYPos < size.height) {
curYPos += increment;
curXPos = curXPos == 0.0 ? 8.0 : 0.0;
path.lineTo(curXPos, curYPos);
}
path.lineTo(size.width, size.height);
path.lineTo(size.width, 0.0);
path.close();
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
Try this
class CustomClipPath extends CustomClipper<Path> {
#override
Path getClip(Size size) {
Path path = Path();
path.lineTo(size.width, 0.0);
var curYPos = 0.0;
var curXPos = 0.0;
path.lineTo(0.0, 0.0);
var increment = size.height / 30;
while (curYPos < size.height) {
curYPos += increment;
curXPos = curXPos == 0 ? 8 : 0;
path.lineTo(curXPos, curYPos);
}
path.lineTo(size.width, size.height);
path.lineTo(size.width, 0.0);
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}