Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement eraser feature for flutter drawing app

There is a video about creating a drawing app by flutter (YouTube) which support to draw lines / points when user tapping on screen but I can't find a feature / way to erase what user had drawn like Android native (like here) especially for lines. I can't just overlaying some colour like white on them because I have background image under the gesture detector.

Can anybody give me some advised about it?

My Sample Project:

import 'dart:ui';

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Offset> points = <Offset>[];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: GestureDetector(
            onPanUpdate: (DragUpdateDetails details) {
              if (details.localPosition.dx < 0) {
                return;
              }
              RenderBox oRenderBox = context.findRenderObject();
              Offset oLocationPoints =
                  oRenderBox.localToGlobal(details.localPosition);
              setState(() {
                this.points = new List.from(this.points..add(oLocationPoints));
              });
            },
            onPanEnd: (DragEndDetails details) => this.points.add(null),
            child: CustomPaint(
                painter: SignaturePainter(
                    points: this.points),
                size: Size.infinite)),
      ),
    );
  }
}

class SignaturePainter extends CustomPainter {
  List<Offset> points = <Offset>[];

  SignaturePainter({this.points});
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.red
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 3.0;
    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != null && points[i + 1] != null) {
        canvas.drawLine(points[i], points[i + 1], paint);
      }
    }
  }

  @override
  bool shouldRepaint(SignaturePainter oldDelegate) {
    return oldDelegate.points != points;
  }
}

Thanks.

like image 945
Anson Woo Avatar asked Jan 06 '20 04:01

Anson Woo


People also ask

What is draw the UI in flutter?

Drawing the UI is one of the core features of every visual app framework. In this tutorial, you’ll build a drawing app in Flutter to explore Flutter’s capability to render and control a custom user interface. You’ll learn to control every pixel on the screen with the help of CustomPaint widgets.

How to create a material design drawer in flutter?

In Flutter, use the Drawer widget in combination with a Scaffold to create a layout with a Material Design drawer. This recipe uses the following steps: Create a Scaffold. Add a drawer. Populate the drawer with items. Close the drawer programmatically. 1. Create a Scaffold To add a drawer to the app, wrap it in a Scaffold widget.

What is Flutter’s colortoolbar?

Note: Even though the component is called ColorToolbar, it also contains the New/Clear buttons. Flutter’s Canvas is an interface for recording graphical operations. It can be used to draw shapes, images, texts and nearly everything else on the screen with pixel precision. To create and access the Canvas, you’ll use a widget called CustomPaint.

How do I use flutter on Android Studio?

Click Open an existing Android Studio project and choose the starter folder from your unzipped download. Run the flutter create . command in the starter folder to generate the android and ios folders. Next, download your dependencies by double-clicking pubspec.yaml on the left panel, then clicking pub get at the top of your screen.


1 Answers

Use saveLayer() and restore() with BlendMode.clear.

From BlendMode.clear:

When using Canvas.saveLayer and Canvas.restore, the blend mode of the Paint given to the Canvas.saveLayer will be applied when Canvas.restore is called. Each call to Canvas.saveLayer introduces a new layer onto which shapes and images are painted; when Canvas.restore is called, that layer is then composited onto the parent layer, with the source being the most-recently-drawn shapes and images, and the destination being the parent layer

Example:

@override
void paint(Canvas canvas, Size size) {
  // default blendMode=BlendMode.srcOver
  final _blendMode = BlendMode.clear;

  // let's pretend this rectangle is an image.
  // in this case, we don't want anything erased from the image, 
  // and we also want the image to be drawn under the eraser.
  canvas.drawRect(Rect.fromLTWH(100, 100, 100, 100), Paint()..color=Colors.white);

  // after having drawn our image, we start a new layer using saveLayer().
  canvas.saveLayer(Rect.fromLTWH(0, 0, size.width, size.height), Paint());

  // drawing the line that should be erased partially.
  canvas.drawLine(
    Offset(100, 100), Offset(200, 200), Paint()..color = Colors.black..strokeWidth = 5.0);

  // erasing parts of the first line where intersected with this line.
  canvas.drawLine(
    Offset(100, 200), Offset(200, 100), Paint()..color=Colors.red..strokeWidth = 5.0..blendMode=_blendMode);

  // first composite this layer and then draw it over the previously drawn layers.
  canvas.restore();

  // move on with other draw commands..
}
like image 51
user3872620 Avatar answered Sep 20 '22 21:09

user3872620