简体   繁体   English

如何在颤动中绘制自定义形状并拖动该形状?

[英]How to draw custom shape in flutter and drag that shape around?

At the moment I can draw rectangles using CustomPainter.目前我可以使用 CustomPainter 绘制矩形。 Below the code inside the paint method of my CustomPainter.在我的 CustomPainter 的paint方法中的代码下方。

for (var rectPoints in rectangles) {
  paint.color = rectPoints.color;
  paint.strokeWidth = rectPoints.strokeWidth;
  if (rectPoints.selected != null && rectPoints.selected == true) {
    paint.color = Colors.black45;
  }
  var rect = Rect.fromLTWH(
      rectPoints.startPoint.dx,
      rectPoints.startPoint.dy,
      rectPoints.endPoint.dx - rectPoints.startPoint.dx,
      rectPoints.endPoint.dy - rectPoints.startPoint.dy);
  canvas.drawRect(rect, paint);
}

var rect = Rect.fromLTWH(startPoint.dx, startPoint.dy,
    endPoint.dx - startPoint.dx, endPoint.dy - startPoint.dy);
canvas.drawRect(rect, paint);

A rectangle is a custom object with startPoint, endPoint and some other properties needed to draw that specific rectangle.矩形是一个自定义对象,具有 startPoint、endPoint 和绘制该特定矩形所需的一些其他属性。 Now I want to select a rectangle and re-position it.现在我想选择一个矩形并重新定位它。 Any help would be appreciated.任何帮助,将不胜感激。 Thanks谢谢

You'll need to track the state of the rectangles' positions independent of the canvas drawing.您需要独立于画布绘图跟踪矩形位置的状态。 The easiest way to do that is to use a StatefulWidget.最简单的方法是使用 StatefulWidget。 You'll also need to use a GestureDetector to capture the pan events.您还需要使用 GestureDetector 来捕获平移事件。 Then you can wire up the gesture details to the position of the rectangles and call the painter to redraw everything.然后,您可以将手势细节连接到矩形的位置,并调用画家重新绘制所有内容。

Here's a simple app that shows how to do it with one rectangle.这是一个简单的应用程序,展示了如何使用一个矩形来完成。 Should be straightforward to expand it to handle multiple ones.将其扩展以处理多个应该很简单。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Draggable Custom Painter',
      home: Scaffold(
        body: CustomPainterDraggable(),
      ),
    );
  }
}

class CustomPainterDraggable extends StatefulWidget {
  @override
  _CustomPainterDraggableState createState() => _CustomPainterDraggableState();
}

class _CustomPainterDraggableState extends State<CustomPainterDraggable> {
  var xPos = 0.0;
  var yPos = 0.0;
  final width = 100.0;
  final height = 100.0;
  bool _dragging = false;

  /// Is the point (x, y) inside the rect?
  bool _insideRect(double x, double y) =>
      x >= xPos && x <= xPos + width && y >= yPos && y <= yPos + height;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onPanStart: (details) => _dragging = _insideRect(
        details.globalPosition.dx,
        details.globalPosition.dy,
      ),
      onPanEnd: (details) {
        _dragging = false;
      },
      onPanUpdate: (details) {
        if (_dragging) {
          setState(() {
            xPos += details.delta.dx;
            yPos += details.delta.dy;
          });
        }
      },
      child: Container(
        color: Colors.white,
        child: CustomPaint(
          painter: RectanglePainter(Rect.fromLTWH(xPos, yPos, width, height)),
          child: Container(),
        ),
      ),
    );
  }
}

class RectanglePainter extends CustomPainter {
  RectanglePainter(this.rect);
  final Rect rect;

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawRect(rect, Paint());
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

I have developed a library called touchable for the purpose of adding gesture callbacks to each individual shape you draw on the canvas.我开发了一个名为touchable的库,目的是为您在画布上绘制的每个单独的形状添加手势回调。 You can draw your shapes and add onPanUpdate or onTapDown callbacks to drag your shape around.您可以绘制形状并添加onPanUpdateonTapDown回调来拖动您的形状。

Here's what you can do to detect touch and drag on your circle.您可以执行以下操作来检测您的圈子上的触摸和拖动。

Here's a small example taken directly from the pub dev site :这是一个直接取自 pub dev site 的小例子:

Wrap your CustomPaint widget with CanvasTouchDetector.使用 CanvasTouchDetector 包装您的 CustomPaint 小部件。 It takes a builder function as argument that expects your CustomPaint widget as shown below.它需要一个构建器函数作为参数,期望您的 CustomPaint 小部件如下所示。

import 'package:touchable/touchable.dart';


CanvasTouchDetector(
    builder: (context) => 
        CustomPaint(
            painter: MyPainter(context)
        )
)

Inside your CustomPainter class's paint method , create and use the TouchyCanvas object (using the context obtained from the CanvasTouchDetector and canvas) to draw your shape and you can give gesture callbacks like onPanUpdate , onTapDown here to detect your drag events.在您的 CustomPainter 类的绘制方法中,创建并使用 TouchyCanvas 对象(使用从 CanvasTouchDetector 和画布获得的上下文)来绘制您的形状,您可以在此处提供 onPanUpdate 、 onTapDown 等手势回调来检测您的拖动事件。

var myCanvas = TouchyCanvas(context,canvas);
myCanvas.drawRect( rect , Paint() , onPanUpdate: (detail){
    //This callback runs when you drag this rectangle. Details of the location can be got from the detail object.
    //Do stuff here. Probably change your state and animate
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM