简单绘制
This commit is contained in:
102
lib/paper/conform_dialog.dart
Normal file
102
lib/paper/conform_dialog.dart
Normal 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
14
lib/paper/model.dart
Normal 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,
|
||||
});
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user