flutter 图片编辑矩形 editBox

实现一个四边可以拖拽 整体可以移动的 用于编辑图片的矩形框
初始矩形 可以滑动生成
长按四边区域 或着内部 进入编辑状态

代码如下

import 'package:flutter/material.dart';

class EditBox extends StatefulWidget {
  @override
  _EditBoxState createState() => _EditBoxState();
}

class _EditBoxState extends State {
  BoxRect? boxRect = BoxRect(null, null, false);
  BoxType boxType = BoxType.init;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('editBox'),
      ),
      body: GestureDetector(
        onPanDown: _onPanDown,
        onPanEnd: _onPanEnd,
        onPanUpdate: _onPanUpdate,
        onLongPressMoveUpdate: _onMove,
        onLongPressEnd: _onMoveEnd,
        onLongPressStart: _onMoveStart,
        child: CustomPaint(
          painter: BoxPainter(boxRect!),
          size: Size.infinite,
        ),
      ),
    );
  }

  _onPanDown(DragDownDetails details) {
    if (boxType == BoxType.init) {
      boxRect!.start = details.localPosition;
      setState(() {});
    }
  }

  _onPanUpdate(DragUpdateDetails details) {
    if (boxType == BoxType.init) {
      boxRect!.end = details.localPosition;
      setState(() {});
    }
  }

  Offset? start;

  Offset? end;

  _onMoveStart(LongPressStartDetails details) {
    if (boxType == BoxType.greatOk) {
      start = boxRect!.start;
      end = boxRect!.end;
      var offset = details.localPosition;
      if (boxRect!.rect1.contains(offset)) {
        boxType = BoxType.moveBox1;
      } else if (boxRect!.rect2.contains(offset)) {
        boxType = BoxType.moveBox2;
      } else if (boxRect!.rect3.contains(offset)) {
        boxType = BoxType.moveBox3;
      } else if (boxRect!.rect4.contains(offset)) {
        boxType = BoxType.moveBox4;
      } else if (boxRect!.rect.contains(offset)) {
        boxType = BoxType.moveBox;
      }
      setState(() {});
    }
  }

  _onMove(LongPressMoveUpdateDetails details) {
    var offset = details.offsetFromOrigin;
    switch (boxType) {
      case BoxType.moveBox:
        boxRect!.start = Offset(start!.dx + offset.dx, start!.dy + offset.dy);
        boxRect!.end = Offset(end!.dx + offset.dx, end!.dy + offset.dy);
        break;
      case BoxType.moveBox1:
        boxRect!.start = Offset(start!.dx + offset.dx, start!.dy + offset.dy);
        break;
      case BoxType.moveBox2:
        boxRect!.start = Offset(start!.dx, start!.dy + offset.dy);
        boxRect!.end = Offset(end!.dx + offset.dx, end!.dy);
        break;
      case BoxType.moveBox3:
        boxRect!.start = Offset(start!.dx + offset.dx, start!.dy);
        boxRect!.end = Offset(end!.dx, end!.dy + offset.dy);
        break;
      case BoxType.moveBox4:
        boxRect!.end = Offset(end!.dx + offset.dx, end!.dy + offset.dy);
        break;
    }
    setState(() {});
  }

  _onMoveEnd(LongPressEndDetails details) {
    boxType = BoxType.greatOk;
  }

  _onPanEnd(DragEndDetails details) {
    if (boxType == BoxType.init) {
      boxType = BoxType.greatOk;
      boxRect!.needSide = true;
      setState(() {});
    }
  }
}

class BoxPainter extends CustomPainter {
  BoxPainter(this.boxRect);

  BoxRect? boxRect;

  @override
  void paint(Canvas canvas, Size size) {
    Offset? start = boxRect!.start;
    Offset? end = boxRect!.end;
    if (start != null && end != null) {
      Paint paint = Paint()
        ..color = Colors.red
        ..style = PaintingStyle.stroke
        ..strokeWidth = 1;
      Rect rect = boxRect!.rect;
      canvas.drawRect(rect, paint);
      if (boxRect!.needSide == true) {
        Paint paint = Paint()
          ..color = Colors.red
          ..style = PaintingStyle.fill;
        canvas.drawRect(boxRect!.rect1, paint);
        canvas.drawRect(boxRect!.rect2, paint);
        canvas.drawRect(boxRect!.rect3, paint);
        canvas.drawRect(boxRect!.rect4, paint);
      }
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }
}

class BoxRect {
  BoxRect(this.start, this.end, this.needSide);

  Offset? start;
  Offset? end;
  bool needSide;

  Rect get rect {
    return Rect.fromLTRB(start!.dx, start!.dy, end!.dx, end!.dy);
  }

  Rect get rect1 {
    return Rect.fromLTRB(start!.dx, start!.dy, start!.dx + 10, start!.dy + 10);
  }

  Rect get rect2 {
    return Rect.fromLTRB(end!.dx - 10, start!.dy, end!.dx, start!.dy + 10);
  }

  Rect get rect3 {
    return Rect.fromLTRB(start!.dx, end!.dy - 10, start!.dx + 10, end!.dy);
  }

  Rect get rect4 {
    return Rect.fromLTRB(end!.dx - 10, end!.dy - 10, end!.dx, end!.dy);
  }
}

enum BoxType {
  init,
  greatOk,
  moveBox,
  moveBox1,
  moveBox2,
  moveBox3,
  moveBox4,
}

直接引用此page即可

你可能感兴趣的:(flutter成长,canvas,flutter,矩形编辑)