Search code examples
flutterdartcanvasgesturedetectorflutter-custompainter

Moving Circle in customer painter with gesture detector not working


I am trying to use gesture detector to move the red point that i draw in custom painter around the xy plot that i draw in a seperate custom painter but i cant seem to get it to work. I would like to thank any help give in advance.


Solution

  • import 'package:flutter/material.dart';
    
     void main() {
      runApp(const MyApp());
     }
    
    class MyApp extends StatefulWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      State<MyApp> createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      bool isDown = false;
      var xPos = 5.0;
      var yPos = 5.0;
    
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: Builder(builder: (BuildContext context) {
              return Scaffold(
                body: Center(
                  child: Container(
                    alignment: Alignment.center,
                    height: MediaQuery.of(context).size.height * 0.3,
                    width: MediaQuery.of(context).size.width,
                    color: Colors.grey,
                    constraints: BoxConstraints(
                      maxHeight: MediaQuery.of(context).size.height * 0.3,
                    ),
                    padding:
                        const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
                    child: LayoutBuilder(
                        builder: (_, constraints) => Container(
                              width: constraints.widthConstraints().maxWidth,
                              height: constraints.widthConstraints().maxHeight,
                              color: Colors.white,
                              child: Stack(children: [
                                // plotting X Y axis
                                SizedBox(
                                    width: constraints.widthConstraints().maxWidth,
                                    height:
                                        constraints.widthConstraints().maxHeight,
                                    child: CustomPaint(painter: PlotPainter())),
    
                                GestureDetector(
                                  onPanUpdate: (details) {
                                    final tapPos = details.localPosition;
    
                                    if (tapPos.dx > 5 &&
                                        tapPos.dx <
                                            constraints
                                                .widthConstraints()
                                                .maxWidth) {
                                      setState(() {
                                        xPos = tapPos.dx - 5;
                                        yPos = tapPos.dy - 5;
                                      });
                                    }
    
                                    if (tapPos.dy > 5 &&
                                        tapPos.dy <
                                            constraints
                                                .widthConstraints()
                                                .maxHeight) {
                                      setState(() {
                                        yPos = tapPos.dy - 5;
                                      });
                                    }
                                  },
                                  child: SizedBox(
                                      width:
                                          constraints.widthConstraints().maxWidth,
                                      height:
                                          constraints.widthConstraints().maxHeight,
                                      child: CustomPaint(
                                          painter: PointsPainter(xPos, yPos))),
                                ),
                                // plotting points
                              ]),
                            )),
                  ),
                ),
              );
            }));
      }
    }
    
    class PointsPainter extends CustomPainter {
      PointsPainter(this.xPos, this.yPos);
      double xPos;
      double yPos;
    
      @override
      void paint(Canvas canvas, Size size) {
        // TODO: implement points
        final midY = size.height / 2;
        final midX = size.width / 2;
        final Circlepaint = Paint()
          ..style = PaintingStyle.fill
          ..color = Colors.red;
        canvas.drawCircle(Offset(xPos, yPos), 5, Circlepaint);
      }
    
      @override
      bool shouldRepaint(CustomPainter oldDelegate) {
        // TODO: implement shouldRepaint
        return true;
      }
    }
    
    // drawing the x y axis
    class PlotPainter extends CustomPainter {
      @override
      void paint(Canvas canvas, Size size) {
        final midY = size.height / 2;
        final midX = size.width / 2;
        final paint = Paint()
          ..style = PaintingStyle.fill
          ..color = Colors.black
          ..strokeWidth = 1.0;
        final textPainterx = TextPainter(
            text: const TextSpan(
              text: 'x',
              style: TextStyle(
                color: Colors.black,
                fontSize: 15,
              ),
            ),
            textDirection: TextDirection.ltr,
            textAlign: TextAlign.center);
        final textPaintery = TextPainter(
            text: const TextSpan(
              text: 'y',
              style: TextStyle(
                color: Colors.black,
                fontSize: 13,
              ),
            ),
            textDirection: TextDirection.ltr,
            textAlign: TextAlign.center);
        // X axis
        canvas.drawLine(Offset(0, midY), Offset(size.width, midY), paint);
        //y Axis
        canvas.drawLine(Offset(midX, 0), Offset(midX, size.height), paint);
        //arrow head of the X-Y Axis
        canvas.drawLine(
            Offset(size.width, midY), Offset(size.width - 5, midY - 3), paint);
        canvas.drawLine(
            Offset(size.width, midY), Offset(size.width - 5, midY + 3), paint);
        canvas.drawLine(Offset(midX, 0), Offset(midX - 3, 5), paint);
        canvas.drawLine(Offset(midX, 0), Offset(midX + 3, 5), paint);
    
        textPainterx.layout();
        textPaintery.layout();
        // Draw the text  X at the X axis
        textPainterx.paint(canvas, Offset(size.width - 7, midY + 1));
        // Draw the text  y at the Y axis
        textPaintery.paint(canvas, Offset(midX + 5, 0));
      }
    
      @override
      bool shouldRepaint(CustomPainter oldDelegate) => false;
    }
    

    The Problem was that you did not wrap the custom painter inside gesture detector now that is working fine now you only have to add condition that it will not go more up and down on given height