I want to create different kind of shapes (like a rectangle, line or circle) over an image background canvas and edit those shape with corner points for resizing. How can I able to do that with flutter?
Shapes customization dragging corners is similar to this JavaScript framework Fabric.js
and the result should be like this:
I solved the issue by writing this below code:
The first part of the code from Scaffold:
if (_imageWidget != null) ...[
FittedBox(
fit: BoxFit.fill,
child: GestureDetector(
onPanStart: (DragStartDetails details) {
// get distance from points to check if is in circle
int indexMatch = -1;
for (int i = 0; i < _points.length; i++) {
double distance = sqrt(
pow(details.localPosition.dx - _points[i].dx, 2) +
pow(details.localPosition.dy - _points[i].dy, 2));
if (distance <= 30) {
indexMatch = i;
break;
}
}
if (indexMatch != -1) {
_currentlyDraggedIndex = indexMatch;
}
},
onPanUpdate: (DragUpdateDetails details) {
if (_currentlyDraggedIndex != -1) {
setState(() {
_points = List.from(_points);
_points[_currentlyDraggedIndex] = details.localPosition;
});
}
},
onPanEnd: (_) {
setState(() {
_currentlyDraggedIndex = -1;
});
},
child: SizedBox(
width: _image.width.toDouble(),
height: _image.height.toDouble(),
child: CustomPaint(
painter: RectanglePainter(
points: _points, clear: _clear, image: _image),
),
),
),
)
]
The Second Part
class RectanglePainter extends CustomPainter {
List<Offset> points;
bool clear;
final ui.Image image;
RectanglePainter(
{@required this.points, @required this.clear, @required this.image});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.red
..strokeCap = StrokeCap.square
..style = PaintingStyle.fill
..strokeWidth = 2;
final outputRect =
Rect.fromPoints(ui.Offset.zero, ui.Offset(size.width, size.height));
final Size imageSize =
Size(image.width.toDouble(), image.height.toDouble());
final FittedSizes sizes =
applyBoxFit(BoxFit.contain, imageSize, outputRect.size);
final Rect inputSubrect =
Alignment.center.inscribe(sizes.source, Offset.zero & imageSize);
final Rect outputSubrect =
Alignment.center.inscribe(sizes.destination, outputRect);
canvas.drawImageRect(image, inputSubrect, outputSubrect, paint);
if (!clear) {
final circlePaint = Paint()
..color = Colors.red
..strokeCap = StrokeCap.square
..style = PaintingStyle.fill
..blendMode = BlendMode.multiply
..strokeWidth = 2;
for (int i = 0; i < points.length; i++) {
if (i + 1 == points.length) {
canvas.drawLine(points[i], points[0], paint);
} else {
canvas.drawLine(points[i], points[i + 1], paint);
}
canvas.drawCircle(points[i], 10, circlePaint);
}
}
}
@override
bool shouldRepaint(RectanglePainter oldPainter) =>
oldPainter.points != points || clear;
}