我有 flutter 绘图应用程序,我在其中使用图层绘图。我一直坚持在程序中实现橡皮擦,问题是当我绘制当前路径并使用橡皮擦时,我看不到画布上的指针移动,我只看到指针抬起时的结果擦除路径。当我绘制通常的路径而不是擦除时,运动是可见的。如果路径是在“橡皮擦模式”下完成的,我会使用
canvas.saveLayer
、BlendMode.clear
和 canvas.restore
。
这是我用于绘制当前路径的自定义 Painter:
class SingleLinePainter extends CustomPainter {
final Stroke? line;
final StrokeOptions options;
Color currentColor = Colors.black;
SingleLinePainter(
{required this.currentColor, required this.line, required this.options});
void setColorForLayer(Color color) {
currentColor = color;
}
@override
Future<void> paint(Canvas canvas, Size size) async {
Paint paint = Paint();
var _blendMode = BlendMode.srcOver;
if (line!.isEraser) {
canvas.saveLayer(null, Paint());
_blendMode = BlendMode.clear;
}
paint.blendMode = _blendMode;
paint.color = currentColor;
final outlinePoints = getStroke(
line!.points,
size: options.size,
thinning: options.thinning,
smoothing: options.smoothing,
streamline: options.streamline,
taperStart: options.taperStart,
capStart: options.capStart,
taperEnd: options.taperEnd,
capEnd: options.capEnd,
simulatePressure: options.simulatePressure,
isComplete: options.isComplete,
);
final path = Path();
if (outlinePoints.isEmpty) {
return;
} else if (outlinePoints.length < 2) {
path.addOval(Rect.fromCircle(
center: Offset(outlinePoints[0].x, outlinePoints[0].y), radius: 1));
} else {
path.moveTo(outlinePoints[0].x, outlinePoints[0].y);
for (int i = 1; i < outlinePoints.length - 1; ++i) {
final p0 = outlinePoints[i];
final p1 = outlinePoints[i + 1];
path.quadraticBezierTo(
p0.x, p0.y, (p0.x + p1.x) / 2, (p0.y + p1.y) / 2);
}
}
canvas.drawPath(path, paint);
if (line!.isEraser) {
canvas.restore();
}
}
@override
bool shouldRepaint(SingleLinePainter oldDelegate) {
return true;
}
}
我的用于构建当前路径的小部件:
Widget buildCurrentPath(BuildContext context) {
return Listener(
onPointerDown: onPointerDown,
onPointerMove: onPointerMove,
onPointerUp: onPointerUp,
child: RepaintBoundary(
child: Container(
color: Colors.transparent,
width: widget.width,
height: widget.height,
child: StreamBuilder<Stroke>(
stream: currentLineStreamController.stream,
builder: (context, snapshot) {
return CustomPaint(
painter: SingleLinePainter(
currentColor: pickerColor,
line: line == null ? null : line!,
options: options,
),
);
})),
),
);
}
如果我不使用canvas.saveLayer + canvas.restore,我将看到指针移动,但橡皮擦将擦除所有先前图层的路径(为了简化,想象一下我正在背景图像上绘制,并且该路径将删除它),但我只想删除当前图层上的路径。
我遇到了这个问题。在进行擦除时,我看到沿着拖动路径创建了一条黑线。一旦我的路径完成,路径沿线的区域就会被擦除。仅当操作完成后,它才不会在我拖动时擦除。有谁知道如何在拖动时启用blendMode.clear?