How do you rotate an object drawn on a canvas in Flutter (not the whole canvas, just the object)?
The following does not work. Error is: This expression has a type of 'void' so its value can't be used.
Transform.rotate(
angle: pi,
child: canvas.drawPath(
getTrianglePath(Offset(secondhandX, secondhandY)),
secondhandBrush));
Here is the full code:
// imports omitted
class TimerDialPainter extends CustomPainter {
Path getTrianglePath(Offset position) {
return Path()
..moveTo(position.dx - 20, position.dy - 20)
..lineTo(position.dx + 40, position.dy + 40)
..lineTo(position.dx - 20, position.dy + 40)
..lineTo(position.dx - 20, position.dy - 20);
}
#override
void paint(Canvas canvas, Size size) {
int centerX = size.width / 2;
int centerY = size.height / 2;
int secondsArc = 60;
Paint countBrush = Paint()
..color = (Colors.red)
..style = PaintingStyle.fill
..strokeWidth = 3;
var secondhandX = centerX + 80 * cos(secondsArc * pi / 180);
var secondhandY = centerY + 80 * sin(secondsArc * pi / 180);
Transform.rotate(
angle: pi/3,
child: canvas.drawPath(
getTrianglePath(Offset(secondhandX, secondhandY)),
countBrush));
} //I feel this is not a right place to solve this??
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
Try rotating the canvas and paint it. Then rotate it back to previous value
#override
void paint(Canvas canvas, Size size) {
double centerX = size.width / 2;
double centerY = size.height / 2;
int secondsArc = 60;
Paint countBrush = Paint()
..color = (Colors.red)
..style = PaintingStyle.fill
..strokeWidth = 3;
num secondhandX = centerX + 80 * cos(secondsArc * pi / 180);
num secondhandY = centerY + 80 * sin(secondsArc * pi / 180);
canvas.rotate(40);
canvas.drawPath(
getTrianglePath(Offset(secondhandX.toDouble(), secondhandY.toDouble())),
countBrush);
canvas.rotate(0);
}
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.
My first day learning flutter, can someone help me understand why my setState is not working?
Making a basic clock app.
The main part is the initState where I am trying to make it so that the Paint function which creates the clock UI is updated once every second so my second hand is updated in real-time.
import 'dart:math';
import 'package:flutter/material.dart';
class ClockView extends StatefulWidget{
#override
_ClockViewState createState() => _ClockViewState();
}
class _ClockViewState extends State<ClockView>{
#override void initState() {
Timer.periodic(Duration(seconds: 1), (timer) {setState(() {
});});
super.initState();
}
#override
Widget build(BuildContext context){
return Container(
width: 300,
height: 300,
child: Transform.rotate(
angle: -pi/2,
child: CustomPaint(
painter: ClockPainter(),
),
),
);
}
}
class ClockPainter extends CustomPainter{
#override
void paint(Canvas canvas, Size size) {
var CenterX = size.width/2;
var CenterY = size.height/2;
var CenterTrue = Offset(CenterX, CenterY);
var CRadius = min(CenterY, CenterY);
var SecHandBrush = Paint()..strokeCap = StrokeCap.round ..color = Colors.orange ..style = PaintingStyle.stroke ..strokeWidth = 4;
var MinHandBrush = Paint()..strokeCap = StrokeCap.round ..shader = RadialGradient(colors: [Colors.lightBlue, Colors.pink]).createShader(Rect.fromCircle(center: CenterTrue, radius: CRadius)) ..style = PaintingStyle.stroke ..strokeWidth = 8;
var HrHandBrush = Paint()..strokeCap = StrokeCap.round ..shader = RadialGradient(colors: [Colors.deepPurpleAccent, Colors.redAccent]).createShader(Rect.fromCircle(center: CenterTrue, radius: CRadius/2)) ..style = PaintingStyle.stroke ..strokeWidth = 10;
var FillBrush = Paint()..color = Color(0xFF444974);
var OutlineBrush = Paint()..color = Color(0xFFEAECFF) ..style = PaintingStyle.stroke ..strokeWidth = 5;
var CenterBrush = Paint()..color = Color(0xFFEAECFF);
canvas.drawCircle(CenterTrue, CRadius - 50, FillBrush);
canvas.drawCircle(CenterTrue, CRadius - 50.1, OutlineBrush);
var SecHandX = CenterX + 80 * cos(DateTime.now().second * 6 * pi/180);
var SecHandY = CenterX + 80 * sin(DateTime.now().second * 6 * pi/180);
canvas.drawLine(CenterTrue, Offset(SecHandX, SecHandY), SecHandBrush);
var MinHandX = CenterX + 75 * cos(DateTime.now().minute * 6 * pi/180);
var MinHandY = CenterX + 75 * sin(DateTime.now().minute * 6 * pi/180);
canvas.drawLine(CenterTrue, Offset(MinHandX,MinHandY), MinHandBrush);
var HrHandX = CenterX + 60 * cos((DateTime.now().hour * 30 + DateTime.now().minute * 0.5) * pi/180);
var HrHandY = CenterX + 60 * sin((DateTime.now().hour * 30 + DateTime.now().minute * 0.5) * pi/180);
canvas.drawLine(CenterTrue, Offset(HrHandX,HrHandY), HrHandBrush);
canvas.drawCircle(CenterTrue, 5, CenterBrush);
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}```
Add a widgets binding observer to trigger timer after the initial state build is complete, I would rewrite it as:
import 'dart:math';
import 'package:flutter/material.dart';
class ClockView extends StatefulWidget{
#override
_ClockViewState createState() => _ClockViewState();
}
class _ClockViewState extends State<ClockView>{
void _startTimer(){
WidgetsBinding.instance.endOfFrame.then(
(_) {
if (mounted) {
// do some suff
Timer.periodic(Duration(seconds: 1), (timer) {setState(() {
});});
};
},
);
}
#override void initState() {
_startTimer();
super.initState();
}
#override
Widget build(BuildContext context){
return Container(
width: 300,
height: 300,
child: Transform.rotate(
angle: -pi/2,
child: CustomPaint(
painter: ClockPainter(),
),
),
);
}
}
class ClockPainter extends CustomPainter{
#override
void paint(Canvas canvas, Size size) {
var CenterX = size.width/2;
var CenterY = size.height/2;
var CenterTrue = Offset(CenterX, CenterY);
var CRadius = min(CenterY, CenterY);
var SecHandBrush = Paint()..strokeCap = StrokeCap.round ..color = Colors.orange ..style = PaintingStyle.stroke ..strokeWidth = 4;
var MinHandBrush = Paint()..strokeCap = StrokeCap.round ..shader = RadialGradient(colors: [Colors.lightBlue, Colors.pink]).createShader(Rect.fromCircle(center: CenterTrue, radius: CRadius)) ..style = PaintingStyle.stroke ..strokeWidth = 8;
var HrHandBrush = Paint()..strokeCap = StrokeCap.round ..shader = RadialGradient(colors: [Colors.deepPurpleAccent, Colors.redAccent]).createShader(Rect.fromCircle(center: CenterTrue, radius: CRadius/2)) ..style = PaintingStyle.stroke ..strokeWidth = 10;
var FillBrush = Paint()..color = Color(0xFF444974);
var OutlineBrush = Paint()..color = Color(0xFFEAECFF) ..style = PaintingStyle.stroke ..strokeWidth = 5;
var CenterBrush = Paint()..color = Color(0xFFEAECFF);
canvas.drawCircle(CenterTrue, CRadius - 50, FillBrush);
canvas.drawCircle(CenterTrue, CRadius - 50.1, OutlineBrush);
var SecHandX = CenterX + 80 * cos(DateTime.now().second * 6 * pi/180);
var SecHandY = CenterX + 80 * sin(DateTime.now().second * 6 * pi/180);
canvas.drawLine(CenterTrue, Offset(SecHandX, SecHandY), SecHandBrush);
var MinHandX = CenterX + 75 * cos(DateTime.now().minute * 6 * pi/180);
var MinHandY = CenterX + 75 * sin(DateTime.now().minute * 6 * pi/180);
canvas.drawLine(CenterTrue, Offset(MinHandX,MinHandY), MinHandBrush);
var HrHandX = CenterX + 60 * cos((DateTime.now().hour * 30 + DateTime.now().minute * 0.5) * pi/180);
var HrHandY = CenterX + 60 * sin((DateTime.now().hour * 30 + DateTime.now().minute * 0.5) * pi/180);
canvas.drawLine(CenterTrue, Offset(HrHandX,HrHandY), HrHandBrush);
canvas.drawCircle(CenterTrue, 5, CenterBrush);
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}```
Note: This problem has been solved. It required a complete re-installation of the flutter package but the code as mentioned in the code works fine on its own without any modifications.
I am looking for the following chart in flutter:
Can anyone provide me any solution?
//First get X,Y Center and radius
double centerX = width / 2;
double centerY = height / 2;
double radius = width / 2;
const numberOfIntervals=5;
//create axis lines
var axisLinePaint = Paint()
..color = viewPortBorderColor
..style = PaintingStyle.stroke
..strokeWidth=1;
//Gridline Paint
var gridlinePaint = Paint()
..color = gridColor
..strokeWidth = 0.6
..style = PaintingStyle.fill;
canvas.drawArc(Rect.fromLTRB(0, 0, width, height),
getRadiansByAngle(-90), getRadiansByAngle(270), true, axisLinePaint);
// Get gap between intervals
int gap=270~/numberOfIntervals;
now creating gridlines:
for (var i = gap; i <= 270; i += gap) {
var thetaAngle = 0;
label=label+(maxVal~/numberOfIntervals);
if (i <= 90) {
thetaAngle = 270 + i;
} else {
thetaAngle = i - 90;
}
var theta = thetaAngle * (pi / 180);
var offSet=Offset(centerX + radius * cos(theta), centerY + radius * sin(theta));
canvas.drawLine(
offSet,
Offset(centerX, centerY),
gridlinePaint);
}
for radian angle:
double getRadiansByAngle(double angle) {
return (angle * pi / 180);
}
Here is full solution:
https://github.com/MoinHashmi/radial_chart_gridlines
If anyone have another suggestion or solution please post.
Great Effort thanks am waiting for this from a long time
I want to draw/insert image and text inside canvas circle but I am unable to do that. I am posting screenshot for better understanding of my requirements
Image
Code
void paint(Canvas canvas, Size size) {
Size size = MediaQuery.of(buildContext).size;
double strokeWidth = 10;
Rect myRect = Offset(-size.width * 0.21, -40) &
Size(size.width * 0.195, size.width * 0.195);
var paint1 = Paint()
..color = Color(0xFF23BBFF)
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke;
var paint2 = Paint()
..color = Color(0xFFFF8623)
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke;
double firstLineRadianStart = 0;
double _unAnswered = 0.30;
double firstLineRadianEnd = (360 * _unAnswered) * pi / 180;
canvas.drawArc(
myRect, firstLineRadianStart, firstLineRadianEnd, false, paint1);
double _learned = 1 - _unAnswered;
double secondLineRadianEnd = getRadians(_learned);
canvas.drawArc(
myRect, firstLineRadianEnd, secondLineRadianEnd, false, paint2);
}
double getRadians(double value) {
return (360 * value) * pi / 180;
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => true;
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.