9
This commit is contained in:
194
lib/cases/paper/paper.dart
Normal file
194
lib/cases/paper/paper.dart
Normal file
@@ -0,0 +1,194 @@
|
||||
import 'dart:math';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'color_selector.dart';
|
||||
import 'conform_dialog.dart';
|
||||
|
||||
import 'model.dart';
|
||||
import 'paper_app_bar.dart';
|
||||
import 'stork_width_selector.dart';
|
||||
|
||||
class Paper extends StatefulWidget {
|
||||
const Paper({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<Paper> createState() => _PaperState();
|
||||
}
|
||||
|
||||
class _PaperState extends State<Paper> with AutomaticKeepAliveClientMixin {
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
|
||||
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,
|
||||
Colors.pink,
|
||||
Colors.grey,
|
||||
Colors.redAccent,
|
||||
Colors.orangeAccent,
|
||||
Colors.yellowAccent,
|
||||
Colors.greenAccent,
|
||||
Colors.blueAccent,
|
||||
Colors.indigoAccent,
|
||||
Colors.purpleAccent,
|
||||
Colors.pinkAccent,
|
||||
];
|
||||
|
||||
// 支持的线粗
|
||||
final List<double> supportStorkWidths = [1, 2, 4, 6, 8, 10];
|
||||
|
||||
List<Line> _historyLines = [];
|
||||
|
||||
void _back() {
|
||||
Line line = _lines.removeLast();
|
||||
_historyLines.add(line);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void _revocation() {
|
||||
Line line = _historyLines.removeLast();
|
||||
_lines.add(line);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: PaperAppBar(
|
||||
onClear: _showClearDialog,
|
||||
onBack: _lines.isEmpty ? null : _back,
|
||||
onRevocation: _historyLines.isEmpty ? null : _revocation,
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onPanStart: _onPanStart,
|
||||
onPanUpdate: _onPanUpdate,
|
||||
child: CustomPaint(
|
||||
painter: PaperPainter(lines: _lines),
|
||||
child: ConstrainedBox(constraints: const BoxConstraints.expand()),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ColorSelector(
|
||||
supportColors: supportColors,
|
||||
activeIndex: _activeColorIndex,
|
||||
onSelect: _onSelectColor,
|
||||
),
|
||||
),
|
||||
StorkWidthSelector(
|
||||
supportStorkWidths: supportStorkWidths,
|
||||
color: supportColors[_activeColorIndex],
|
||||
activeIndex: _activeStorkWidthIndex,
|
||||
onSelect: _onSelectStorkWidth,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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],
|
||||
strokeWidth: supportStorkWidths[_activeStorkWidthIndex],
|
||||
color: supportColors[_activeColorIndex],
|
||||
));
|
||||
}
|
||||
|
||||
void _onPanUpdate(DragUpdateDetails details) {
|
||||
Offset point = details.localPosition;
|
||||
double distance = (_lines.last.points.last - point).distance;
|
||||
if (distance > 5) {
|
||||
_lines.last.points.add(details.localPosition);
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
void _onSelectStorkWidth(int index) {
|
||||
if (index != _activeStorkWidthIndex) {
|
||||
setState(() {
|
||||
_activeStorkWidthIndex = index;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _onSelectColor(int index) {
|
||||
if (index != _activeColorIndex) {
|
||||
setState(() {
|
||||
_activeColorIndex = index;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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) {
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
drawLine(canvas, lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
///根据点位绘制线
|
||||
void drawLine(Canvas canvas, Line line) {
|
||||
_paint.color = line.color;
|
||||
_paint.strokeWidth = line.strokeWidth;
|
||||
canvas.drawPoints(PointMode.polygon, line.points, _paint);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(CustomPainter oldDelegate) => true;
|
||||
}
|
||||
Reference in New Issue
Block a user