recalculate bounding rect of stroke when adding point

add eraser prototype functionality
This commit is contained in:
lukas-heiligenbrunner 2022-10-28 23:59:12 +02:00
parent c5bce47222
commit 57cff08218
2 changed files with 92 additions and 56 deletions

View File

@ -3,6 +3,11 @@ import 'dart:ui';
class Stroke { class Stroke {
List<Point> points = <Point>[]; List<Point> points = <Point>[];
double _minx = double.infinity;
double _maxx = double.negativeInfinity;
double _miny = double.infinity;
double _maxy = double.negativeInfinity;
@override @override
String toString() { String toString() {
return 'Stroke{points: $points}'; return 'Stroke{points: $points}';
@ -10,6 +15,16 @@ class Stroke {
void addPoint(Point point) { void addPoint(Point point) {
points.add(point); points.add(point);
// update bounding rect
if (point.point.dx < _minx) _minx = point.point.dx;
if (point.point.dx > _maxx) _maxx = point.point.dx;
if (point.point.dy < _miny) _miny = point.point.dy;
if (point.point.dy > _maxy) _maxy = point.point.dy;
}
Rect getBoundingRect() {
return Rect.fromPoints(Offset(_minx, _miny), Offset(_maxx, _maxy));
} }
Stroke.fromPoints(this.points); Stroke.fromPoints(this.points);

View File

@ -111,6 +111,27 @@ class _DrawingPageState extends State<DrawingPage> {
return; return;
} }
// todo outsource this eraser pen
if (eraseractive) {
// todo dynamic eraser size
final eraserrect = Rect.fromCircle(center: pos, radius: 3);
for (final stroke in _strokes) {
// check if delete action was within bounding rect of stroke
if (stroke.getBoundingRect().contains(pos)) {
// check if eraser hit an point within its range
for (final pt in stroke.points) {
if (eraserrect.contains(pt.point)) {
setState(() {
_strokes = List.from(_strokes)..remove(stroke);
});
return;
}
}
}
}
return;
}
if (allowDrawWithFinger || event.kind != PointerDeviceKind.touch) { if (allowDrawWithFinger || event.kind != PointerDeviceKind.touch) {
final pts = _strokes.last.points; final pts = _strokes.last.points;
@ -134,71 +155,71 @@ class _DrawingPageState extends State<DrawingPage> {
Widget _buildCanvas() { Widget _buildCanvas() {
final size = MediaQuery.of(context).size; final size = MediaQuery.of(context).size;
return Scaffold( return Listener(
body: Listener( behavior: HitTestBehavior.opaque,
behavior: HitTestBehavior.opaque, onPointerMove: (e) => _onPointerMove(e, size),
onPointerMove: (e) => _onPointerMove(e, size), onPointerSignal: (event) {
onPointerSignal: (event) { print('Button: ${event.buttons}');
print('Button: ${event.buttons}'); },
}, onPointerDown: (event) {
onPointerDown: (event) { print('Button: ${event.buttons}');
print('Button: ${event.buttons}');
if (allowDrawWithFinger || event.kind != PointerDeviceKind.touch) { if (allowDrawWithFinger || event.kind != PointerDeviceKind.touch) {
Offset pos = event.localPosition; Offset pos = event.localPosition;
final scale = calcPageDependentScale(zoom, a4Page, size); final scale = calcPageDependentScale(zoom, a4Page, size);
pos = translateScreenToDocumentPoint(pos, scale, offset); pos = translateScreenToDocumentPoint(pos, scale, offset);
// todo line drawn on edge where line left page // todo line drawn on edge where line left page
if (!a4Page.contains(pos)) return; if (!a4Page.contains(pos)) return;
if (eraseractive) return; if (eraseractive) return;
setState(() {
_strokes = List.from(_strokes)
..add(Stroke.fromPoints(
[Point(pos, _calcTiltedWidth(3.0, event.tilt))]));
});
}
},
onPointerUp: (event) {
if (eraseractive) return;
if (allowDrawWithFinger || event.kind != PointerDeviceKind.touch) {
if (_strokes.last.points.length <= 1) {
// if the line consists only of one point (point) add endpoint as the same to allow drawing a line
// todo maybe solve this in custompainter in future
setState(() { setState(() {
_strokes = List.from(_strokes) _strokes = List.from(_strokes, growable: false)
..add(Stroke.fromPoints( ..last.points.add(_strokes.last.points.last);
[Point(pos, _calcTiltedWidth(3.0, event.tilt))]));
}); });
} else {
setState(() {});
} }
},
onPointerUp: (event) {
if (allowDrawWithFinger || event.kind != PointerDeviceKind.touch) {
if (_strokes.last.points.length <= 1) {
// if the line consists only of one point (point) add endpoint as the same to allow drawing a line
// todo maybe solve this in custompainter in future
setState(() {
_strokes = List.from(_strokes, growable: false)
..last.points.add(_strokes.last.points.last);
});
} else {
setState(() {});
}
print(_strokes.length); print(_strokes.length);
print(_strokes.last.points.length); print(_strokes.last.points.length);
} }
}, },
child: GestureDetector( child: GestureDetector(
onScaleUpdate: (details) { onScaleUpdate: (details) {
if (details.scale == 1.0) return; if (details.scale == 1.0) return;
setState(() { setState(() {
zoom = (basezoom * details.scale).clamp(0.25, 5.0); zoom = (basezoom * details.scale).clamp(0.25, 5.0);
}); });
}, },
onScaleEnd: (details) { onScaleEnd: (details) {
basezoom = zoom; basezoom = zoom;
}, },
onSecondaryTap: () { onSecondaryTap: () {
print('secctab'); print('secctab');
}, },
onTertiaryTapDown: (details) { onTertiaryTapDown: (details) {
print('tertiary button'); print('tertiary button');
}, },
child: CustomPaint( child: CustomPaint(
painter: MyPainter(strokes: _strokes, offset: offset, zoom: zoom), painter: MyPainter(strokes: _strokes, offset: offset, zoom: zoom),
size: Size.infinite, size: Size.infinite,
),
), ),
), ),
); );