Fluter Canvas tutorial 05 | Gesture with the custom painter?
In this tutorial, you can learn how to use a gesture, also how to draw a pie chart.
When we draw our own shape with theCustomPainter
, but if you do not know how to interact with the user, it will be a bit dull for the user, so we should know how to use the gesture to plenty our interaction. If you do not know how to use the custom or the canvas, please say the fore tutorials.
0. What to implement?
As often, we should know what result we will get. We have this situation, when we scroll on the screen from up to down, we want the shape that we draw to rotate from up to down. When we scroll on the screen from down to up, we want to rotate from down to up. In the horizontal direction, we also want a similar effect. Let’s see the gif to get more detail.
1. Define a CustomPainter
As a common step, we should define our painter to draw our own shape. First, we should define our Painter as a name you like.
class CircleTrianglePainter extends CustomPainter {
CircleTrianglePainter({this.scrollLen});
final double scrollLen;
@override
void paint(Canvas canvas, Size size) {}
@override
bool shouldRepaint(CircleTrianglePainter oldDelegate) =>
oldDelegate.scrollLen != scrollLen;
Then, draw a circle with the triangle arc.
void _drawTriCircle(Canvas canvas, Paint paint,
{Offset center,
double radius,
List<double> sources,
List<Color> colors,
double startRadian}) {
assert(sources != null && sources.length > 0);
assert(colors != null && colors.length > 0);
var total = 0.0;
for (var d in sources) {
total += d;
}
List<double> radians = [];
for (var data in sources) {
radians.add(data * 2 * pi / total);
}
for (int i = 0; i < radians.length; i++) {
paint.color = colors[i % colors.length];
canvas.drawArc(Rect.fromCircle(center: center, radius: radius),
startRadian, radians[i], true, paint);
startRadian += radians[i];
}
}
In our paint(canvas,size)
function, draw our shape.
if (size.width > 1.0 && size.height > 1.0) {
print(">1.9");
_sizeUtil.logicSize = size;
}
var paint = Paint()
..style = PaintingStyle.fill
..color = BLUE_NORMAL
..strokeWidth = 2.0
..isAntiAlias = true;
paint.color = Colors.grey[900];
// canvas.drawCircle(
// Offset(_sizeUtil.getAxisX(250), _sizeUtil.getAxisY(250.0)),
// _sizeUtil.getAxisBoth(200.0),
// paint);
paint.color = RED_DARK1;
paint.strokeWidth = 20;
paint.style = PaintingStyle.stroke;
var center = Offset(
_sizeUtil.getAxisX(250.0),
_sizeUtil.getAxisY(250.0),
);
var radius = _sizeUtil.getAxisBoth(200);
paint.style = PaintingStyle.fill;
// canvas.drawArc(Rect.fromCircle(center: center, radius: radius),
// 1.4 * scrollLen / radius, pi / 2, true, paint);
_drawTriCircle(
canvas,
paint,
sources: [1,2,1,1,1,1,1],
colors: [
RED_DARK1,
BLUE_NORMAL,
GREEN_NORMAL,
RED_DARK5,
YELLOW_NORMAL
],
center: center,
radius: radius,
startRadian: 1.4 * scrollLen / radius,
);
canvas.save();
canvas.restore();
Then, our circle is implemented, but you can change the params above. For the next step, let’s see how to use the painter.
2. Use the CustomPaint
Just in your widget, you can use the CustomPaint. Like below.
Container(
width: 300,
height: 300,
child: CustomPaint(
painter: (CircleTrianglePainter(scrollLen: _len)),
child: Container(),
),
),
3. Implement the gesture.
In flutter, if you want to use gesture, you can chooseListenser
or GestureDetector
to meet your requirements. They both are widget, you can use them as a common widget, but GestureDetector
is more rich than Listener
in the flutter. This time we choose GestureDetector
to implement our requirements.
Container(
child: Center(
child: GestureDetector(
onHorizontalDragStart: (detail) {
_x = detail.globalPosition.dx;
},
onVerticalDragStart: (detail) {
_y = detail.globalPosition.dy;
},
onHorizontalDragUpdate: (detail) {
setState(() {
_len -= detail.globalPosition.dx - _x;
_x = detail.globalPosition.dx;
});
},
onVerticalDragUpdate: (detail) {
setState(() {
_len += detail.globalPosition.dy - _y;
_y = detail.globalPosition.dy;
});
},
child: Container(
width: 300,
height: 300,
child: CustomPaint(
painter: (CircleTrianglePainter(scrollLen: _len)),
child: Container(),
),
),
),
))
The GestureDetector has many actions, but we just comply 4 functions for our requirements. We just look at the horizontal direction, the vertical is the same as the horizontal.
onHorizontalDragStart: (detail) {
_x = detail.globalPosition.dx;
},
onHorizontalDragUpdate: (detail) {
setState(() {
_len -= detail.globalPosition.dx - _x;
_x = detail.globalPosition.dx;
});
},
When we drag to start with horizontal, we just record the value of x-axis. When the drag locations are changed, we record the change value with _len
. This value will be used as a start angle for our shape above.
Whole Code in the GitHub, thanks for a star.
Conclusion
We have study how to draw a triangle circle in the flutter and how to add a gesture to it.
- Define a CustomPainter.
- Draw the triangle circle.
- Use the CustomPaint
- Add a GestureDetector to the CustomPaint
The End.
#Facebook page: Flutter Open
#Github: Flutter Open
#Developer Github: Nie Bin