简单绘制

This commit is contained in:
toly
2023-05-08 08:39:09 +08:00
parent 97a0edb982
commit 45eae5c947
3 changed files with 195 additions and 54 deletions

View File

@@ -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: <Widget>[
_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),
),
],
);
}

14
lib/paper/model.dart Normal file
View File

@@ -0,0 +1,14 @@
import 'package:flutter/material.dart';
class Line {
List<Offset> points;
Color color;
double strokeWidth;
Line({
required this.points,
this.color = Colors.black,
this.strokeWidth = 1,
});
}

View File

@@ -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<Paper> {
List<Line> _lines = []; // 线列表
int _activeColorIndex = 0; // 颜色激活索引
int _activeStorkWidthIndex = 0; // 线宽激活索引
// 支持的颜色
final List<Color> supportColors = [
Colors.black, Colors.red, Colors.orange,
Colors.yellow, Colors.green, Colors.blue,
Colors.indigo, Colors.purple,
];
// 支持的线粗
final List<double> 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<Line> lines;
@override
void paint(Canvas canvas, Size size) {
// List<Offset> 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;
}