如何在flutter canvas内渲染按钮?

问题描述 投票:0回答:1

我正在做一个flutter绘制项目,需要实现调整最后一条路径大小的功能。但是当我更改列表中的某些项目时,监听器坏了!我不知道我做错了什么!我有问题的代码是:

    [...]
      Widget buildCurrentPath(BuildContext context) {
        ValueNotifier<DrawingFunction> activeFunction =
            ValueNotifier(DrawingFunction.draw);
    
        return Listener(
          onPointerDown: (details) {
            final box = context.findRenderObject() as RenderBox;
            final offset = box.globalToLocal(details.position);
    
            if (allSketches.value.isNotEmpty) {
              Rect scaleButtonPosition =
                  allSketches.value.last.getScaleButtonPosition();
    
              if (scaleButtonPosition.contains(offset)) {
                print("Scale button pressed");
                activeFunction.value = DrawingFunction.scale;
              }
            }
            if (activeFunction.value == DrawingFunction.draw) {
              currentSketch.value = Sketch.fromDrawingMode(
                Sketch(
                  points: [offset],
                  color: selectedColor.value,
                  size: strokeSize.value,
                ),
                drawingMode.value,
                filled.value,
              );
            }
          },
          onPointerMove: (details) {
            final box = context.findRenderObject() as RenderBox;
            final offset = box.globalToLocal(details.position);
    
            print(activeFunction);
    
            if (activeFunction.value == DrawingFunction.draw) {
              final points = List<Offset>.from(currentSketch.value?.points ?? [])
                ..add(offset);
    
              currentSketch.value = Sketch.fromDrawingMode(
                Sketch(
                    points: points,
                    color: selectedColor.value,
                    size: strokeSize.value),
                drawingMode.value,
                filled.value,
              );
            } else if (activeFunction.value == DrawingFunction.scale) {
              double scale = 0.9;
    
              Sketch sketch = allSketches.value.last;
              Path transformedPath = sketch.path
                  .transform(Matrix4.diagonal3Values(scale, scale, 1).storage);
    
              sketch.path = transformedPath;
              //currentSketch.value = sketch;
            }
          },
          onPointerUp: (details) {
            if (activeFunction.value == DrawingFunction.draw) {
              allSketches.value = List<Sketch>.from(allSketches.value)
                ..add(currentSketch.value!);
    
              currentSketch.value = null;
            }
          },
          child: RepaintBoundary(
    [...]

在此示例中,更新被注释:

//currentSketch.value = sketch;
并且当您单击渲染的按钮并移动指针时,绘图函数保持缩放函数,但是如果我取消注释此行,则指针向下将绘图函数更改为.scale,但 onPointerMove 中断这个和drawingFunction回来画画。

我需要做什么? Flutter 画布有同样的技巧吗?

flutter dart drawing
1个回答
0
投票

要在 Flutter 画布内渲染按钮,您需要使用 CustomPainter 小部件进行自定义绘画,并手动处理按钮单击事件。以下是如何在 Flutter 画布上渲染按钮的基本示例:


import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: Scaffold(
      appBar: AppBar(
        title: Text('Canvas Buttons Example'),
      ),
      body: CanvasButtonDemo(),
    ),
  ));
}

class CanvasButtonDemo extends StatefulWidget {
  @override
  _CanvasButtonDemoState createState() => _CanvasButtonDemoState();
}

class _CanvasButtonDemoState extends State<CanvasButtonDemo> {
  List<Button> buttons = [];

  @override
  void initState() {
    super.initState();
    buttons.add(Button(50, 50, 100, 50, 'Button 1', onPressed: () {
      print('Button 1 pressed');
    }));
    buttons.add(Button(50, 150, 100, 50, 'Button 2', onPressed: () {
      print('Button 2 pressed');
    }));
  }

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: Size(double.infinity, double.infinity),
      painter: CanvasButtonPainter(buttons),
    );
  }
}

class Button {
  final double x;
  final double y;
  final double width;
  final double height;
  final String label;
  final VoidCallback onPressed;

  Button(this.x, this.y, this.width, this.height, this.label, {required this.onPressed});
}

class CanvasButtonPainter extends CustomPainter {
  final List<Button> buttons;

  CanvasButtonPainter(this.buttons);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.fill;

    for (var button in buttons) {
      final rect = Rect.fromPoints(Offset(button.x, button.y), Offset(button.x + button.width, button.y + button.height));
      canvas.drawRect(rect, paint);

      final textPainter = TextPainter(
        text: TextSpan(
          text: button.label,
          style: TextStyle(color: Colors.white, fontSize: 20.0),
        ),
        textDirection: TextDirection.ltr,
      );

      textPainter.layout(minWidth: 0, maxWidth: button.width);
      textPainter.paint(canvas, Offset(button.x, button.y));

      // Add touch handling
      canvas.drawRect(rect, paint);
      canvas.drawRect(rect, Paint()..color = Colors.transparent);
      final buttonRect = rect.shift(Offset(0, size.height));
      canvas.drawRect(buttonRect, Paint()..color = Colors.transparent);

      final touchArea = Rect.fromPoints(rect.topLeft, buttonRect.bottomRight);
      canvas.drawRRect(
          RRect.fromRectAndRadius(touchArea, Radius.circular(8.0)), Paint()..color = Colors.transparent);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}


此代码定义了一个 Button 类来存储按钮属性,例如位置、大小、标签和 onPressed 回调。 CanvasButtonPainter 类用于在画布上绘制按钮,它还处理触摸事件以检测按钮按下情况。 这是一个基本示例,您可以根据您的特定用例的需要进一步自定义它。

© www.soinside.com 2019 - 2024. All rights reserved.