I have this shape
enter image description here
I want to flip it to be like this
enter image description here
this is the original code
class CustomMenuClipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
Paint paint = Paint();
paint.color = Colors.white;
final width = size.width;
final height = size.height;
Path path = Path();
path.moveTo(0, 0);
path.quadraticBezierTo(0, 8, 10, 16);
path.quadraticBezierTo(width - 1, height / 2 - 20, width, height / 2);
path.quadraticBezierTo(width + 1, height / 2 + 20, 10, height - 16);
path.quadraticBezierTo(0, height - 8, 0, height);
path.close();
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return true;
}
}
this is the github repository
I don't mind if it comes to a half-circle.
I think is should be something like this:
Path getClip(Size size) {
Paint paint = Paint();
paint.color = Colors.white;
final width = size.width;
final height = size.height;
Path path = Path();
path.moveTo(width, 0);
path.quadraticBezierTo(16, 10, 8, 0);
path.quadraticBezierTo(height / 2, width, height / 2 - 20 ,width - 1);
path.quadraticBezierTo( height - 16, 10, height / 2 + 20, height - 16width + 1);
path.quadraticBezierTo(height, 0, height - 8, 0);
path.close();
return path;
}
I would not recommend this, since different devices might reproduce different behaviors. Maybe using size.width and size.height might be a better idea for responsiveness.
Related
I am trying to make a game level map UI with flutter. I am trying to do this with Custompainter. I can draw path line but don't know how to get this level pointers and add buttons/image widget to those points. I didn't find good solution in web.
My code below:
class LinePainter extends CustomPainter {
int totalLevel ;
LinePainter(this.totalLevel);
#override
void paint(Canvas canvas, Size size) {
var paint = Paint()
..color = AppColors.primaryColor
..style = PaintingStyle.stroke
..strokeWidth = 10;
var path = Path();
path.moveTo(0, size.height * 0.125);
path.lineTo(size.width- 50, size.height * 0.125);
path.lineTo(size.width- 50, size.height * 0.375);
path.lineTo(50, size.height * 0.375);
path.lineTo(50, size.height * 0.625);
path.lineTo(size.width- 50, size.height * 0.625);
path.lineTo(size.width- 50, size.height * 0.875);
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}}
Please help to find best solution.
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)
)
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;
}
I want to draw animated border around the square container with infinity loop (never stop) like this photo , I'm trying animated container bust not help me
so can anyone tell me how to implement line animation
Edit **
I'm using this code to draw the square but I can't make it build with animation
class RadialPainter extends CustomPainter {
final double progressRemoval;
final Color color;
final StrokeCap strokeCap;
final PaintingStyle paintingStyle;
final double strokeWidth;
final double progress;
RadialPainter(
{this.progressRemoval,
this.color,
this.strokeWidth,
this.strokeCap,
this.paintingStyle,
this.progress});
#override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..strokeWidth = strokeWidth
..color = color
..style = paintingStyle
..strokeCap = strokeCap;
var progressRemoval = 0.50;
var path = Path();
//LINEA SUPERIOR DEL CUADRADO
path.moveTo((size.width * 0.30), 0);
path.quadraticBezierTo((size.width * 0.30), 0, size.width, 0);
//LATERAL DERECHO
path.moveTo(size.width, 0);
path.quadraticBezierTo(size.width, 0, size.width, size.height);
//LINEA INFERIOR DEL CUADRADO
path.moveTo(size.width, size.height);
path.quadraticBezierTo(size.width, size.height, 0, size.height);
//LINEA IZQUIERDA
path.moveTo(0, size.height);
path.quadraticBezierTo(0, (size.height * 0.75), 0, ((size.height * 0.75)));
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(RadialPainter oldDelegate) {
return oldDelegate.progress != progress;
}
}
enter link description here
I'm currently blocked trying to create a widget (like a tooltip box) that is represented by the image below. I should probably be able to create it by relying on a Painter class, but i'm not familiar doing so...
https://pasteboard.co/IgccNxD.png
(it's small, yes, max height = ~35px)
The code ended being something like:
void paint(Canvas canvas, Size size) {
Paint p = Paint()
..color = Colors.red
..isAntiAlias = true
..style = PaintingStyle.fill;
Offset nw = Offset(0, 0);
Offset se = Offset(size.width, size.height * 0.8);
final Rect rect = Rect.fromPoints(nw, se);
final RRect r = RRect.fromRectAndRadius(rect, Radius.circular(10));
canvas.drawRRect(r, p);
Offset bottomPoint = Offset((size.width / 2), size.height);
Offset rightPoint = Offset((size.width / 2) * 0.80, size.height * 0.80);
Offset leftPoint = Offset((size.width / 2) * 1.20, size.height * 0.80);
var path1 = Path()
..moveTo(rightPoint.dx, rightPoint.dy)
..lineTo(bottomPoint.dx, bottomPoint.dy)
..lineTo(leftPoint.dx, leftPoint.dy)
..lineTo(rightPoint.dx, rightPoint.dy);
canvas.drawPath(path1, p);
}
For the text inside, I've stacked it above this painting.