From 45eae5c9472425a477f8d8282d2f4284b781e113 Mon Sep 17 00:00:00 2001 From: toly <1981462002@qq.com> Date: Mon, 8 May 2023 08:39:09 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AE=80=E5=8D=95=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/paper/conform_dialog.dart | 102 ++++++++++++++++++++++++++ lib/paper/model.dart | 14 ++++ lib/paper/paper.dart | 133 ++++++++++++++++++++-------------- 3 files changed, 195 insertions(+), 54 deletions(-) create mode 100644 lib/paper/conform_dialog.dart create mode 100644 lib/paper/model.dart diff --git a/lib/paper/conform_dialog.dart b/lib/paper/conform_dialog.dart new file mode 100644 index 0000000..fcfee66 --- /dev/null +++ b/lib/paper/conform_dialog.dart @@ -0,0 +1,102 @@ +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020-04-23 +/// contact me by email 1981462002@qq.com +/// 说明: + +class ConformDialog extends StatelessWidget { + final String title; + final String msg; + final String conformText; + final VoidCallback onConform; + + ConformDialog({ + Key? key, + required this.title, + required this.msg, + required this.onConform, + this.conformText = '删除', + }) : super(key: key); + + final ButtonStyle conformStyle = ElevatedButton.styleFrom( + backgroundColor: Colors.redAccent, + foregroundColor: Colors.white, + elevation: 0, + minimumSize: const Size(70, 35), + padding: EdgeInsets.zero, + shape: const StadiumBorder(), + ); + + final ButtonStyle cancelStyle = OutlinedButton.styleFrom( + minimumSize: const Size(70, 35), + elevation: 0, + padding: EdgeInsets.zero, + shape: const StadiumBorder(), + ); + + @override + Widget build(BuildContext context) { + return Dialog( + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + _buildTitle(), + _buildMessage(), + _buildButtons(context), + ], + ), + ), + ); + } + + Widget _buildTitle()=>Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.warning_amber_rounded, color: Colors.orange), + const SizedBox( + width: 10, + ), + Text( + title, + style: const TextStyle( + fontSize: 16, fontWeight: FontWeight.bold), + ), + ], + ); + + Widget _buildMessage()=>Padding( + padding: const EdgeInsets.only( + top: 15, + bottom: 15, + ), + child: Text( + msg, + style: const TextStyle(fontSize: 14), + ), + ); + + Widget _buildButtons(BuildContext context) => Row( + children: [ + const Spacer(), + OutlinedButton( + onPressed: Navigator.of(context).pop, + style: cancelStyle, + child: const Text( + '取消', + style: TextStyle(fontSize: 12, color: Colors.grey), + )), + const SizedBox(width: 10), + ElevatedButton( + onPressed: onConform, + style: conformStyle, + child: Text(conformText), + ), + ], + ); +} diff --git a/lib/paper/model.dart b/lib/paper/model.dart new file mode 100644 index 0000000..f65bbca --- /dev/null +++ b/lib/paper/model.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; + +class Line { + List points; + Color color; + double strokeWidth; + + Line({ + required this.points, + this.color = Colors.black, + this.strokeWidth = 1, + }); + +} \ No newline at end of file diff --git a/lib/paper/paper.dart b/lib/paper/paper.dart index 768977b..ef2e0a6 100644 --- a/lib/paper/paper.dart +++ b/lib/paper/paper.dart @@ -2,7 +2,9 @@ import 'dart:math'; import 'dart:ui'; import 'package:flutter/material.dart'; +import 'package:flutter_first_station/paper/conform_dialog.dart'; +import 'model.dart'; import 'paper_app_bar.dart'; class Paper extends StatefulWidget { @@ -13,76 +15,99 @@ class Paper extends StatefulWidget { } class _PaperState extends State { + List _lines = []; // 线列表 + + int _activeColorIndex = 0; // 颜色激活索引 + int _activeStorkWidthIndex = 0; // 线宽激活索引 + + // 支持的颜色 + final List supportColors = [ + Colors.black, Colors.red, Colors.orange, + Colors.yellow, Colors.green, Colors.blue, + Colors.indigo, Colors.purple, + ]; + + // 支持的线粗 + final List supportStorkWidths = [1,2, 4, 6, 8, 10]; + + @override Widget build(BuildContext context) { return Scaffold( appBar: PaperAppBar( - onClear: _clear, + onClear: _showClearDialog, ), - body: CustomPaint( - painter: PaperPainter(), - child: ConstrainedBox(constraints: const BoxConstraints.expand()), + body: GestureDetector( + onPanStart: _onPanStart, + onPanUpdate: _onPanUpdate, + child: CustomPaint( + painter: PaperPainter( + lines: _lines + ), + child: ConstrainedBox(constraints: const BoxConstraints.expand()), + ), ), ); } - void _clear() {} + void _showClearDialog() { + String msg = "您的当前操作会清空绘制内容,是否确定删除!"; + showDialog( + context: context, + builder: (ctx) => ConformDialog( + title: '清空提示', + conformText: '确定', + msg: msg, + onConform: _clear, + )); + } + + void _clear(){ + _lines.clear(); + Navigator.of(context).pop(); + setState(() { + + }); + } + + void _onPanStart(DragStartDetails details) { + _lines.add(Line(points: [details.localPosition],)); + } + + void _onPanUpdate(DragUpdateDetails details) { + _lines.last.points.add(details.localPosition); + setState(() { + + }); + } } class PaperPainter extends CustomPainter { + PaperPainter({ + required this.lines, + }) { + _paint = Paint() + ..style = PaintingStyle.stroke + ..strokeCap = StrokeCap.round; + } + + late Paint _paint; + final List lines; + @override void paint(Canvas canvas, Size size) { - // List points = const [ - // Offset(100,100), - // Offset(100,150), - // Offset(150,150), - // Offset(200,100), - // ]; - // - // paint.strokeWidth = 10; - // - // paint.strokeCap = StrokeCap.round; - // - // - // canvas.drawPoints(PointMode.polygon, points , paint); - // canvas.translate(0, 150); - Paint paint = Paint(); + for (int i = 0; i < lines.length; i++) { + drawLine(canvas, lines[i]); + } + } - canvas.drawCircle(Offset(100, 100), 50, paint); - paint.style = PaintingStyle.stroke; - canvas.drawCircle(Offset(250, 100), 50, paint); - canvas.translate(0, 150); - - paint.strokeWidth = 2; - Rect rect = Rect.fromCenter(center: Offset(100, 100), width: 100, height: 80); - canvas.drawRect(rect, paint); - paint.style = PaintingStyle.fill; - RRect rrect = RRect.fromRectXY(rect.translate(150, 0), 8, 8); - canvas.drawRRect(rrect, paint); - - canvas.translate(0, 150); - paint.strokeWidth = 2; - Rect overRect = Rect.fromCenter(center: Offset(100, 100), width: 100, height: 80); - canvas.drawOval(overRect, paint); - paint.style = PaintingStyle.stroke; - canvas.drawArc(overRect.translate(150, 0), 0, pi*1.3,true,paint); - // RRect rrect = RRect.fromRectXY(rect.translate(150, 0), 8, 8); - // canvas.drawRRect(rrect, paint); - - - // paint.style = PaintingStyle.stroke; - // canvas.drawCircle(Offset(250, 100), 50, paint); - - // paint.color = Colors.red; - // paint.style = PaintingStyle.stroke; - // paint.strokeJoin = StrokeJoin.round; - // canvas.drawPoints(PointMode.polygon, points , paint); - // canvas.translate(0, 150); - // - // paint.color = Colors.blue; - // canvas.drawPoints(PointMode.polygon, points , paint); + ///根据点位绘制线 + void drawLine(Canvas canvas, Line line) { + _paint.color = line.color; + _paint.strokeWidth = line.strokeWidth; + canvas.drawPoints(PointMode.polygon, line.points, _paint); } @override - bool shouldRepaint(covariant CustomPainter oldDelegate) => true; + bool shouldRepaint(CustomPainter oldDelegate) => true; }