Fluter Canvas tutorial 05 | Gesture with the custom painter?

NieBin
flutteropen
Published in
4 min readJan 8, 2019

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(),
),
),
triangle circle

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.

  1. Define a CustomPainter.
  2. Draw the triangle circle.
  3. Use the CustomPaint
  4. Add a GestureDetector to the CustomPaint

The End.

#Facebook page: Flutter Open

#Github: Flutter Open

#Developer Github: Nie Bin

Whole Code in the GitHub, thanks for a star.

--

--