Flutter, PaintingStyle.fill not working as expected - flutter

import 'package:flutter/material.dart';
import 'dart:math' as math;
class PaintHalfHexagon extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Colors.black
..style = PaintingStyle.fill;
Path path = Path();
path.moveTo(size.width * 0.1, size.height * 0.34);
path.quadraticBezierTo(size.width * 0.1, size.height * 0.26,
size.width * 0.3, size.height * 0.28);
path.moveTo(size.width * 0.5, size.height * 0.34);
path.quadraticBezierTo(size.width * 0.5, size.height * 0.26,
size.width * 0.3, size.height * 0.28);
path.moveTo(size.width * 0.1, size.height * 0.34);
path.lineTo(size.width * 0.5, size.height * 0.34);
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
// return oldDelegate._lineOnefraction != _lineOnefraction;
return false;
}
}
When I stroked it, the shape came out perfectly, and when I filled it to fill the color, it came out in a very strange shape.
PaintingStyle.fill
PaintingStyle.stroke
What`s the problem and how to solve this?

I assume you want to draw an object with the shape of the 'stroke' version, but filled like the 'fill' version. The problem is that calling moveTo breaks your current path and starts a new one at the coordinates you specify. Even if you draw your separate paths back together so that they look like they touch, as far as the engine is concerned they are not contiguous. Therefore, when you use PaintingStyle.fill it has no idea that it should fill that space in. The result in your example is that it closed the path of each bezier separately, and filled each bezier separately.
You can refactor to remove the moveTo calls, e.g.:
path.moveTo(size.width * 0.1, size.height * 0.34);
path.quadraticBezierTo(size.width * 0.1, size.height * 0.26,
size.width * 0.3, size.height * 0.28);
path.quadraticBezierTo(size.width * 0.5, size.height * 0.26,
size.width * 0.5, size.height * 0.34);
path.lineTo(size.width * 0.5, size.height * 0.34);

Related

How can I draw a dotted path in flutter using canvas.drawLine

I need help, I am trying to google to find out how I can implement a dotted path in canva when using canva.drawPath. I can only see code of canva.drawLine, But I can't find for canva.drawPath. Please see the code below.
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
class CustomPainterWeb extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
double dashHeight = 5, dashSpace = 3, startY = 0;
var paint = Paint();
var path = Path();
paint.style = PaintingStyle.stroke;
paint.strokeWidth = 0.5;
paint.color = HexColor("#718096");
// First service curve
path.moveTo(size.width / 5.0, size.height / 4.2);
path.cubicTo(size.width / 5.0, size.height / 2.3, size.width / 2.0,
size.height / 3.6, size.width / 2.0, size.height / 2.3);
// First service arrow
path.moveTo(size.width / 2.0, size.height / 2.29);
path.lineTo(size.width / 1.96, size.height / 2.34);
path.moveTo(size.width / 2.0, size.height / 2.29);
path.lineTo(size.width / 2.04, size.height / 2.34);
// Second service curve
path.moveTo(size.width / 1.8, size.height / 1.8);
path.cubicTo(size.width / 1.8, size.height / 1.3, size.width * 0.3,
size.height * 0.6, size.width * 0.3, size.height / 1.3);
// second service arrow
path.moveTo(size.width * 0.30, size.height / 1.3);
path.lineTo(size.width * 0.29, size.height / 1.32);
path.moveTo(size.width * 0.299, size.height / 1.3);
path.lineTo(size.width * 0.31, size.height / 1.32);
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return false;
}
}

Flutter interactive chart graph

I am searching for a package in flutter where I can create a chart with an interactable graph, where I can manipulate data with drag and drop
Example:
An example chart
Now I want to ajust each value in that step diagram with drag and drop (up and down)
I found high charts and some of my collegues used that to do so but not in flutter so im not sure if that is possible there.
Firstly, It's totally possible to create interactive charts with Flutter.
You can either implement it yourself with a CustomPainter and some widgets.
Here's an example of a Curved basic chart.
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;
}
You can also check out some specialized packages as: syncfusion_flutter_charts
I think you'll be interested in the step_line chart.

How to clip the container with half circle outward in bottom center

I have this design which i want to create
I have tried this code :
#override
Path getClip(Size size) {
var path = Path();
path.lineTo(0.0, size.height - 50);
path.lineTo(size.width / 2 - 35 , size.height -50);
path.quadraticBezierTo(size.width / 2 - 35 , size.height , size.width / 2 + 120 , size.height);
path.quadraticBezierTo(size.width /2 + 35 , size.height, size.width / 2 + 35, size.height - 50);
path.lineTo(size.width / 2 + size.width, size.height - 50);
path.lineTo(size.width, 0.0);
path.close();
return path;
}
But i am failing to do ... The result i am getting is
I can't understand what i am doing wrong. Pleas help me also i want that shadow as well after clipping at the bottom. but i am not getting that to make things visible i change the colour of scaffold to grey
Playing with the height and adding shadow to clip path i finally get close to desire result.
var path = Path();
path.lineTo(0.0, size.height - 50);
path.lineTo(size.width / 2 - 35 , size.height -50);
path.quadraticBezierTo(size.width / 2 - 35 , size.height - 25 , size.width / 2 , size.height -20);
path.quadraticBezierTo(size.width /2 + 35 , size.height -25 , size.width / 2 + 35, size.height - 50);
path.lineTo(size.width / 2 + size.width, size.height - 50);
path.lineTo(size.width, 0.0);
path.close();
return path;
The image container now looks like this
you really only need to draw one curve and not two.
Path getClip(Size size) {
final Path path = Path()
..lineTo(0, size.height - 35)
..lineTo((size.width / 2) - 50, size.height - 35)
..quadraticBezierTo(size.width / 2, size.height + 35, (size.width / 2) + 50, size.height - 35,)
..lineTo(size.width, size.height - 35)
..lineTo(size.width, 0)
..close();
return path;
}

How to round Arc edges in flutter?

I need to create an arc chart as following:
Using canvas I've created this one:
My code:
class CustomChartPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
Rect drawingRect = Rect.fromCircle(center: Offset(size.width / 2, size.height / 2), radius: size.width / 2);
final Paint paint2 = Paint();
paint2.color = const Color.fromRGBO(0, 0, 0, 0.04);
paint2.style = PaintingStyle.stroke;
paint2.strokeWidth = 50;
canvas.drawCircle(Offset(size.width / 2, size.height / 2), size.width / 2, paint2);
canvas.drawArc(drawingRect,
-pi / 2 + 0.35,
pi - 0.35,
false,
greenPaint);
canvas.drawArc(drawingRect,
pi / 2 + 0.35,
pi - 0.35,
false,
orangePaint);
}
}
How can I round edges of arcs as presented on the first picture?
As #pskink mentioned, the solution is to use Paint.strokeCap, more precisely: paint.strokeCap = StrokeCap.round

Flutter design wave quadraticBezierTo

in this link we have solved design wave quadraticBezierTo, but that's half of wave quadraticBezierTo and i want to have full design like with this screen shot:
and now my question is how can we change this below code to have another half design on right side of that
this below class make this
class WaveClipperTwo extends CustomClipper<Path> {
bool reverse;
WaveClipperTwo({this.reverse = false});
final int _coefficient = 16;
double get _minStep => 1 / _coefficient;
double get _preCenter => _minStep * (_coefficient / 2 - 1);
double get _postCenter => _minStep * (_coefficient / 2 + 1);
double get _preEnd => _minStep * (_coefficient - 2);
#override
Path getClip(Size size) {
var path = Path();
path.moveTo(0.0, 0.0);
if(!reverse) {
path.lineTo(0.0, size.height - 20.0);
path.lineTo(size.width * _preCenter, size.height - 20.0);
path.cubicTo(size.width/2, size.height - 20.0, size.width/2, size.height - 40.0, size.width * _postCenter, size.height - 40.0);
path.lineTo(size.width * _preEnd, size.height - 40.0);
path.quadraticBezierTo(size.width, size.height - 40.0, size.width, size.height - 20.0);
path.lineTo(size.width, 0.0);
path.close();
}else{
path.lineTo(0.0, 20);
path.lineTo(size.width * _preCenter, 20.0);
path.cubicTo(size.width/2, 20.0, size.width/2, 40.0, size.width * _postCenter, 40.0);
path.lineTo(size.width * _preEnd, 40.0);
path.quadraticBezierTo(size.width, 40, size.width, 20.0);
path.lineTo(size.width, 0.0);
path.close();
}
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
Here you are:
Change innerWidth constant when you want to make middle part wider or narrower.
class TopFeedsWaveCurve extends CustomClipper<Path> {
final double innerWidth = 100;
final double innerHeight = 20;
final double topOffcet = 60;
#override
Path getClip(Size size) {
var halfW = innerWidth / 2;
var height = innerHeight + topOffcet;
var path = Path()
..moveTo(0.0, 0.0)
..lineTo(0.0, topOffcet)
..lineTo(size.width / 2 - halfW - innerHeight, topOffcet)
..cubicTo(
size.width / 2 - halfW,
topOffcet,
size.width / 2 - halfW,
height,
size.width / 2 - halfW + innerHeight,
height,
)
..lineTo(size.width / 2 + halfW - innerHeight, height)
..cubicTo(
size.width / 2 + halfW,
height,
size.width / 2 + halfW,
topOffcet,
size.width / 2 + halfW + innerHeight,
topOffcet,
)
..lineTo(size.width, topOffcet)
..lineTo(size.width, 0);
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}