How to create an inner shadow for custom shape in Flutter? - flutter

Below is the custom shape I've want to give an inner shadow to :
Below is the code I've used to create this shape : (The text part is not included in the code)
class TitleContainerPaint extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
Paint x = Paint()..color = Colors.grey ..style = PaintingStyle.fill;
Path a = Path();
a.moveTo(size.height * 0.5, 0);
a.lineTo(size.width * 0.3, 0);
a.cubicTo(size.width * 0.325, 0, size.width * 0.325, size.height * 0.5 - 10, size.width * 0.35, size.height * 0.5 - 10);
a.lineTo(size.width * 0.825, size.height * 0.35);
a.cubicTo(size.width * 0.85, size.height * 0.5 - 10, size.width * 0.85, size.height * 0.15, size.width * 0.875, size.height * 0.15);
a.lineTo(size.width - size.height * 0.25, size.height * 0.15);
a.arcTo(Rect.fromCircle(center: Offset(size.width - size.height * 0.35,size.height * 0.5), radius: size.height * 0.35), -pi/2, pi, false);
a.lineTo(size.width * 0.875, size.height * 0.85);
a.cubicTo(size.width * 0.85, size.height * 0.85, size.width * 0.85, size.height * 0.5 + 10, size.width * 0.825, size.height * 0.5 + 10);
a.lineTo(size.width * 0.35, size.height * 0.65);
a.cubicTo(size.width * 0.325, size.height * 0.5 + 10, size.width * 0.325, size.height, size.width * 0.3, size.height);
a.lineTo(size.height * 0.5, size.height);
a.arcTo(Rect.fromCircle(center: Offset(size.height * 0.5,size.height * 0.5), radius: size.height * 0.5), pi/2, pi, false);
canvas.drawPath(a, x);
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return true;
}
}
As mentioned in the question, my goal is to add an inner shadow to this shape like the image below :
Can someone please help me achieve this?
Thankyou in advance.

Use your paint like this:
Paint x = Paint()
..style = PaintingStyle.fill
..maskFilter = MaskFilter.blur(BlurStyle.inner, 5)
..color = Colors.grey;
Output:

I propose the same approach as given in my other answer. In your case you just use the CustomPaint widget as the child for the inner shadow widget:
InnerShadow(
shadow: const BoxShadow(
blurRadius: 20,
color: Colors.black,
),
child: CustomPaint(painter: TitleContainerPaint()),
)
The complete code could be found here https://codepen.io/priezz/pen/abBRmrb
P.S. Your TitleContainerPaint gives slightly different shape than given in your example image, you'll probably need to tweak it. Maybe it's just the issue with Flutter for Web.

//change the alpha color of your grey color like this
canvas.drawShadow(path, Colors.grey.withAlpha(50), -4.0, false);
Here the shadow will be inner.

Related

How to fill a line depending on a percentage using Canvas in Flutter?

I have a map that displays markers with data. On the right side of the marker there is an indicator in the form of a purple stripe. I need to make this indicator dynamic so that I can set a value in % and, depending on this value, the bar is filled with red. If the value is 100% then a completely red stripe, if 60% then a little more than half of the red color and the rest is green. I was drawing a strip using Canvas, but now I'm facing the problem that I don't know how can I make this strip dynamic, two-colored and dependent on %? I will be grateful for help
class PointPainter extends CustomPainter {
PointPainter({this.isClosed = false});
final bool isClosed;
#override
void paint(Canvas canvas, Size size) {
final strokeWidthThin = size.width * 0.07;
Paint paintMain = Paint()
..style = PaintingStyle.stroke
..strokeWidth = strokeWidthThin
..color = constants.Colors.purpleMain;
Paint paintPurpleThin = Paint()
..style = PaintingStyle.stroke
..strokeWidth = strokeWidthThin
..color = constants.Colors.purpleMain;
Paint paintPurpleBold = Paint()
..style = PaintingStyle.stroke
..strokeWidth = size.width * 0.16
..color = constants.Colors.purpleMain;
Paint paintGreen = Paint()
..style = PaintingStyle.stroke
..strokeWidth = strokeWidthThin
..color = constants.Colors.purpleMainDark.withOpacity(isClosed ? 0.5 : 1);
Paint paintTransparent = Paint()
..style = PaintingStyle.stroke
..strokeWidth = size.width * 0.04
..color = constants.Colors.purpleMainDark;
final pathMain = Path()
..moveTo(size.width / 2, size.height * 1.05)
..lineTo(size.width / 2 - size.width * 0.3, size.height * 0.4)
..arcToPoint(
Offset(size.width - size.width * 0.2, size.height * 0.3),
clockwise: true,
radius: const Radius.circular(0.9),
)
..lineTo(size.width / 2 + size.width * 0.3, size.height * 0.4);
final pathGreen = Path()
..moveTo(size.width / 2 + size.width * 0.3, size.height * 0.4)
..lineTo(size.width / 2, size.height)
..arcToPoint(
Offset(size.width - size.width * 0.22, size.height * 0.26),
clockwise: true,
radius: const Radius.circular(0.9),
);
final pathPurpleThin = Path()
..moveTo(size.width / 2, size.height * 1.05)
..lineTo(size.width / 2 - size.width * 0.3, size.height * 0.4);
final pathPurpleBold = Path()
..moveTo(size.width * 0.54, size.height * 1.03)
..lineTo(size.width / 2 + size.width * 0.3, size.height * 0.45);
final pathTransparent = Path()
..moveTo(size.width * 0.44, size.height)
..lineTo(size.width * 0.58, size.height * 0.68);
pathMain.close();
pathGreen.close();
pathPurpleThin.close();
pathTransparent.close();
if (!isClosed) {
canvas.drawPath(pathMain, paintMain);
canvas.drawPath(pathGreen, paintGreen);
canvas.drawPath(pathPurpleThin, paintPurpleThin);
canvas.drawPath(pathTransparent, paintTransparent);
}
canvas.drawPath(pathPurpleBold, paintPurpleBold);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
body
ClipPath(
clipper: PointClipper(),
child: Container(
width: width,
height: height,
color: constants.Colors.purpleMainDark,
child: CustomPaint(
painter: PointPainter(isClosed: isClosed),
),
),
),
point_clipper
class PointClipper extends CustomClipper<Path> {
PointClipper();
#override
Path getClip(Size size) {
//top
final path0 = Path();
path0..moveTo(size.width / 2, size.height * 0.4)
..lineTo(size.width / 2 - size.width * 0.3, size.height * 0.4)
..arcToPoint(
Offset(size.width - size.width * 0.2, size.height * 0.3),
clockwise: true,
radius: const Radius.circular(0.9),
)
..lineTo(size.width / 2 + size.width * 0.3, size.height * 0.4);
path0.close();
//bottom
path0.moveTo(size.width * 0.43, size.height * 0.9);
path0.quadraticBezierTo(size.width * 0.5, size.height * 1.1,
size.width * 0.57, size.height * 0.9);
path0.quadraticBezierTo(size.width * 0.6, size.height * 0.9,
size.width * 0.43, size.height * 0.9);
path0.close();
//middle
path0..moveTo(size.width * 0.43, size.height * 0.9)
..lineTo(size.width * 0.57, size.height * 0.9)
..lineTo(size.width / 2 + size.width * 0.3, size.height * 0.4)
..lineTo(size.width / 2 - size.width * 0.3, size.height * 0.4);
path0.close();
return path0;
}
#override
bool shouldReclip(PointClipper oldClipper) => true;
}

How to draw Image Inside Circulr path in Canvas in Flutter

Hello can anyone tell me how can i draw image inside circular path with scaled image that fits inside the path. I tried but could not able to figure out and bothering a lot. Please help me.
Paint paint_4 = new Paint()
..color = Colors.black
..style = PaintingStyle.fill
..strokeWidth = 1;
Path path_4 = Path();
path_4.moveTo(size.width * 0.2275000, size.height * 0.2879286);
path_4.cubicTo(
size.width * 0.2528667,
size.height * 0.2879286,
size.width * 0.2928750,
size.height * 0.3193143,
size.width * 0.2928750,
size.height * 0.4000000);
path_4.cubicTo(
size.width * 0.2928750,
size.height * 0.4449143,
size.width * 0.2733667,
size.height * 0.5120714,
size.width * 0.2275000,
size.height * 0.5120714);
path_4.cubicTo(
size.width * 0.2013083,
size.height * 0.5120714,
size.width * 0.1621250,
size.height * 0.4786286,
size.width * 0.1621250,
size.height * 0.4000000);
path_4.cubicTo(
size.width * 0.1621250,
size.height * 0.3550857,
size.width * 0.1808750,
size.height * 0.2879286,
size.width * 0.2275000,
size.height * 0.2879286);
path_4.close();
Circular Path to draw Image and Image need to be properly Scaled to
be visible
How Can I Scale assest image to Circular path in properly visibe or fit
How can i use Matrix4 to scale ImageShader to canvas
canvas.drawPath(
path_4,
Paint()
..shader = ImageShader(images, TileMode.clamp,TileMode.clamp,Matrix4.identity().scaled(0.19, 0.21).storage));
Here Is my Code
class ImagePainters extends StatefulWidget {
#override
_ImagePaintersState createState() => _ImagePaintersState();
}
class _ImagePaintersState extends State<ImagePainters> {
ui.Image myImage;
Future<ui.Image> _loadAssetImage() async {
Completer<ui.Image> completer = new Completer<ui.Image();
AssetImage('assets/face.jpg').resolve(new ImageConfiguration()).addListener(
ImageStreamListener((ImageInfo image, bool synchronousCall) {
setState(() {
myImage = image.image;
});
ui.Image img;
img = image.image;
completer.complete(img);
}));
return completer.future;
}
#override
void initState() {
super.initState();
_loadAssetImage();
}
#override
Widget build(BuildContext context) {
return Center(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: CustomPaint(
size: Size(1000, 1000 * 0.7),
painter: FinalPainter(context, myImage)),
),
);
}
}
Canvas Drawing Class
class FinalPainter extends CustomPainter {
final ui.Image images;
FinalPainter(BuildContext context, this.images);
#override
void paint(Canvas canvas, Size size) {
Paint paint_4 = new Paint()
..color = Colors.black //Color.fromARGB(255, 255, 255, 255)
..style = PaintingStyle.fill
..strokeWidth = 1;
Path path_4 = Path();
path_4.moveTo(size.width * 0.2275000, size.height * 0.2879286);
path_4.cubicTo(
size.width * 0.2528667,
size.height * 0.2879286,
size.width * 0.2928750,
size.height * 0.3193143,
size.width * 0.2928750,
size.height * 0.4000000);
path_4.cubicTo(
size.width * 0.2928750,
size.height * 0.4449143,
size.width * 0.2733667,
size.height * 0.5120714,
size.width * 0.2275000,
size.height * 0.5120714);
path_4.cubicTo(
size.width * 0.2013083,
size.height * 0.5120714,
size.width * 0.1621250,
size.height * 0.4786286,
size.width * 0.1621250,
size.height * 0.4000000);
path_4.cubicTo(
size.width * 0.1621250,
size.height * 0.3550857,
size.width * 0.1808750,
size.height * 0.2879286,
size.width * 0.2275000,
size.height * 0.2879286);
path_4.close();
Image should be properly visible and can be scaled Circular Path to
draw Image and Image need to be properly Scaled to be visible
Face should be visible clearly inside the circular path
canvas.drawPath(path_4, Paint()..shader = ImageShader(images,
TileMode.clamp, TileMode.clamp,
Matrix4.identity().scaled(0.19, 0.21).storage));}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
{return true;}
}

how to create custom chart in flutter

i am trying to create chart like this that has a circular border
i want to create custom like this/
how i am gonna do that , is there any packages that i can modify it and make it like this
If you want to create a chart, you can use syncfusion_flutter_charts
and if you want create curves you can use CustomPaint widget. one example I find in my code for you:
CustomPaint(
painter: CurveBackground(color: \\ yourColor),
child: \\ your child
)
class CurveBackground extends CustomPainter {
final Color color;
CurveBackground({this.color});
#override
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.color = color;
paint.style = PaintingStyle.fill;
var path = Path();
path.moveTo(0, Dimens.size_30());
path.quadraticBezierTo(size.width * 0.4, size.height * 0.1,
size.width * 0.3, size.height * 0.3);
path.quadraticBezierTo(size.width * 0.1, size.height * 0.6,
size.width * 0.45, size.height * 0.7);
path.quadraticBezierTo(
size.width * 1, size.height * 0.9, size.width * 0.9, size.height * 1.0);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}

How to Draw Shapes using Bezier Curves in a Flutter CustomPainter

I am trying to draw the picture below using the flutter customPainter library. How can I draw this shape?
My codes and the result
import 'package:flutter/material.dart';
class CurvePainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
var paint = new Paint();
paint.color = Colors.green[800];
paint.style = PaintingStyle.fill;
var path = new Path();
path.lineTo(0, size.height * 0.3);
path.quadraticBezierTo(size.width * 0.35, size.height * 0.4, size.width * 0.7, size.height * 0.21);
path.quadraticBezierTo(size.width * 0.6, size.height * 0.19, size.width * 0.9, size.height * 0.15);
path.quadraticBezierTo(size.width , size.height * 0.05, size.width * 0.6, 0);
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
The Bézier curves you chose are not the correct ones.
Here I illustrate where I applied which curves. The yellow dots are start & end points and the black dots represent control points.
In the code, I went from left to right (top to bottom) and used arcToPoint instead of conicTo as it works better. Note that arcToPoint draws conic curves as well.
It is just a rough sketch, i.e. the proportions are completely off, but at least I can share the proper Bézier curves you should use in order to achieve your desired output.
#override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.red[800]
..style = PaintingStyle.fill;
final path = new Path()
..moveTo(size.width * .6, 0)
..quadraticBezierTo(
size.width * .7,
size.height * .08,
size.width * .9,
size.height * .05,
)
..arcToPoint(
Offset(
size.width * .93,
size.height * .15,
),
radius: Radius.circular(size.height * .05),
largeArc: true,
)
..cubicTo(
size.width * .6,
size.height * .15,
size.width * .5,
size.height * .46,
0,
size.height * .3,
)
..lineTo(0, 0)
..close();
canvas.drawPath(path, paint);
}
Note that I updated the syntax to use .. cascade notation and the final keyword for the variables.

Paint shape with flutter customPainter widget

How i can paint something like this in flutter with CustomPainter:
image
Try this and tweak the values to your convenience
class CurvedBarPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Colors.black;
Path path = Path();
path.lineTo(0.0, size.height * .58);
path.quadraticBezierTo(size.width * .01, size.height * .95 , size.width * .15, size.height);
path.lineTo(size.width * .85, size.height);
path.quadraticBezierTo(size.width * .99, size.height * .95 , size.width, size.height * .6);
path.lineTo(size.width, size.height * .2);
path.quadraticBezierTo(size.width * .99, size.height * -.02, size.width * .9, 0.0);
path.lineTo(size.width * .8, 0.0);
path.quadraticBezierTo(size.width * .7, size.height * .01, size.width * .65, size.height * .3);
path.quadraticBezierTo(size.width * .5, size.height , size.width * .35, size.height * .3);
path.quadraticBezierTo(size.width * .3, size.height * .01, size.width * .2, 0.0);
path.lineTo(size.width * .1, 0.0);
path.quadraticBezierTo(size.width * .01, size.height * -.02, 0.0, size.height * .2);
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}