This commit is contained in:
toly
2023-12-21 22:06:28 +08:00
parent 8b846f86d3
commit 2f4e8d3564
62 changed files with 6651 additions and 92 deletions

View File

@@ -0,0 +1 @@
export 'p14_page.dart';

View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'package:components/components.dart';
import 's01.dart' as s1;
import 's02.dart' as s2;
import 's03.dart' as s3;
import 's04.dart' as s4;
import 's05.dart' as s5;
class P14Page extends StatelessWidget {
const P14Page({super.key});
@override
Widget build(BuildContext context) {
return const DemoShower(
srcCodeDir: 'draw/p14',
demos: [
s1.Paper(),
s2.Paper(),
s3.Paper(),
s4.Paper(),
s5.Paper(),
],
);
}
}

View File

@@ -0,0 +1,62 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import '../components/coordinate_pro.dart';
/// create by 张风捷特烈 on 2020/5/1
/// contact me by email 1981462002@qq.com
/// 说明:
class Paper extends StatelessWidget {
const Paper({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: CustomPaint(
// 使用CustomPaint
painter: PaperPainter(),
),
);
}
}
class PaperPainter extends CustomPainter {
final Coordinate coordinate = Coordinate();
Offset p1 = Offset(100, 100);
Offset p2 = Offset(120, -60);
Paint _helpPaint = Paint();
@override
void paint(Canvas canvas, Size size) {
coordinate.paint(canvas, size);
canvas.translate(size.width / 2, size.height / 2);
Paint paint = Paint()
..color = Colors.orange
..style = PaintingStyle.stroke
..strokeWidth = 2;
Path path = Path();
path.quadraticBezierTo(p1.dx, p1.dy, p2.dx, p2.dy);
canvas.drawPath(path, paint);
_drawHelp(canvas);
}
void _drawHelp(Canvas canvas) {
_helpPaint
..color = Colors.purple
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
canvas.drawPoints(PointMode.lines,[Offset.zero, p1, p1,p2], _helpPaint..strokeWidth=1);
canvas.drawPoints(PointMode.points, [Offset.zero, p1, p1, p2],
_helpPaint..strokeWidth = 8);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}

View File

@@ -0,0 +1,131 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import '../components/coordinate_pro.dart';
import 'touch_info.dart';
/// create by 张风捷特烈 on 2020/5/1
/// contact me by email 1981462002@qq.com
/// 说明:
class Paper extends StatefulWidget {
const Paper({super.key});
@override
_PaperState createState() => _PaperState();
}
class _PaperState extends State<Paper> {
final TouchInfo touchInfo = TouchInfo();
@override
void dispose() {
touchInfo.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanDown: _onPanDown,
onPanUpdate: _onPanUpdate,
child: Container(
color: Colors.white,
child: CustomPaint(
painter: PaperPainter(repaint: touchInfo),
),
),
);
}
void _onPanDown(DragDownDetails details) {
if (touchInfo.points.length < 3) {
touchInfo.addPoint(details.localPosition);
}else{
judgeZone(details.localPosition);
}
}
void _onPanUpdate(DragUpdateDetails details) {
judgeZone(details.localPosition,update: true);
}
///判断出是否在某点的半径为r圆范围内
bool judgeCircleArea(Offset src, Offset dst, double r) =>
(src - dst).distance <= r;
//判断哪个点被选中
void judgeZone(Offset src,{bool update =false}) {
for (int i = 0; i < touchInfo.points.length; i++) {
if (judgeCircleArea(src, touchInfo.points[i], 15)) {
touchInfo.selectIndex = i;
if(update){
touchInfo.updatePoint(i, src);
}
}
}
}
}
class PaperPainter extends CustomPainter {
final Coordinate coordinate = Coordinate();
Paint _helpPaint = Paint()
..color = Colors.purple
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
final TouchInfo repaint;
PaperPainter({ required this.repaint}) : super(repaint: repaint);
List<Offset> pos = [];
@override
void paint(Canvas canvas, Size size) {
coordinate.paint(canvas, size);
canvas.translate(size.width / 2, size.height / 2);
pos = repaint.points
.map((e) => e.translate(-size.width / 2, -size.height / 2))
.toList();
Path path = Path();
Paint paint = Paint()
..color = Colors.orange
..style = PaintingStyle.stroke
..strokeWidth = 2;
if (pos.length < 3) {
canvas.drawPoints(PointMode.points, pos, _helpPaint..strokeWidth = 8);
} else {
path.moveTo(pos[0].dx, pos[0].dy);
path.quadraticBezierTo(pos[1].dx, pos[1].dy, pos[2].dx, pos[2].dy);
canvas.drawPath(path, paint);
_drawHelp(canvas);
_drawSelectPos(canvas,size);
}
}
void _drawHelp(Canvas canvas) {
_helpPaint..color = Colors.purple;
canvas.drawPoints(PointMode.polygon, pos, _helpPaint..strokeWidth = 1);
canvas.drawPoints(PointMode.points, pos, _helpPaint..strokeWidth = 8);
}
void _drawSelectPos(Canvas canvas,Size size) {
Offset? selectPos = repaint.selectPoint;
if (selectPos == null) return;
selectPos = selectPos.translate(-size.width / 2, -size.height / 2);
canvas.drawCircle(
selectPos,
10,
_helpPaint
..color = Colors.green
..strokeWidth = 2);
}
@override
bool shouldRepaint(PaperPainter oldDelegate) =>
oldDelegate.repaint != repaint;
}

View File

@@ -0,0 +1,127 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import '../components/coordinate_pro.dart';
import 'touch_info.dart';
class Paper extends StatefulWidget {
const Paper({super.key});
@override
_PaperState createState() => _PaperState();
}
class _PaperState extends State<Paper> {
final TouchInfo touchInfo = TouchInfo();
@override
void dispose() {
touchInfo.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanDown: _onPanDown,
onPanUpdate: _onPanUpdate,
child: Container(
color: Colors.white,
child: CustomPaint(
painter: PaperPainter(repaint: touchInfo),
),
),
);
}
void _onPanDown(DragDownDetails details) {
if (touchInfo.points.length < 4) {
touchInfo.addPoint(details.localPosition);
}else{
judgeZone(details.localPosition);
}
}
void _onPanUpdate(DragUpdateDetails details) {
judgeZone(details.localPosition,update: true);
}
///判断出是否在某点的半径为r圆范围内
bool judgeCircleArea(Offset src, Offset dst, double r) =>
(src - dst).distance <= r;
//判断哪个点被选中
void judgeZone(Offset src,{bool update =false}) {
for (int i = 0; i < touchInfo.points.length; i++) {
if (judgeCircleArea(src, touchInfo.points[i], 15)) {
touchInfo.selectIndex = i;
if(update){
touchInfo.updatePoint(i, src);
}
}
}
}
}
class PaperPainter extends CustomPainter {
final Coordinate coordinate = Coordinate();
Paint _helpPaint = Paint()
..color = Colors.purple
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
final TouchInfo repaint;
PaperPainter({required this.repaint}) : super(repaint: repaint);
List<Offset> pos = [];
@override
void paint(Canvas canvas, Size size) {
coordinate.paint(canvas, size);
canvas.translate(size.width / 2, size.height / 2);
pos = repaint.points
.map((e) => e.translate(-size.width / 2, -size.height / 2))
.toList();
Path path = Path();
Paint paint = Paint()
..color = Colors.orange
..style = PaintingStyle.stroke
..strokeWidth = 2;
if (pos.length < 4) {
canvas.drawPoints(PointMode.points, pos, _helpPaint..strokeWidth = 8);
} else {
path.moveTo(pos[0].dx, pos[0].dy);
path.cubicTo(pos[1].dx, pos[1].dy, pos[2].dx, pos[2].dy, pos[3].dx, pos[3].dy);
canvas.drawPath(path, paint);
_drawHelp(canvas);
_drawSelectPos(canvas,size);
}
}
void _drawHelp(Canvas canvas) {
_helpPaint..color = Colors.purple;
canvas.drawPoints(PointMode.polygon, pos, _helpPaint..strokeWidth = 1);
canvas.drawPoints(PointMode.points, pos, _helpPaint..strokeWidth = 8);
}
void _drawSelectPos(Canvas canvas,Size size) {
Offset? selectPos = repaint.selectPoint;
if (selectPos == null) return;
selectPos = selectPos.translate(-size.width / 2, -size.height / 2);
canvas.drawCircle(
selectPos,
10,
_helpPaint
..color = Colors.green
..strokeWidth = 2);
}
@override
bool shouldRepaint(PaperPainter oldDelegate) =>
oldDelegate.repaint != repaint;
}

View File

@@ -0,0 +1,170 @@
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import '../components/coordinate_pro.dart';
import 'touch_info.dart';
/// create by 张风捷特烈 on 2020/5/1
/// contact me by email 1981462002@qq.com
/// 说明:
class Paper extends StatefulWidget {
const Paper({super.key});
@override
_PaperState createState() => _PaperState();
}
class _PaperState extends State<Paper> {
final TouchInfo touchInfo = TouchInfo();
//单位圆(即半径为1)控制线长
final rate = 0.551915024494;
double _radius = 150;
@override
void initState() {
super.initState();
touchInfo.setPoints(_initPoints());
}
@override
void dispose() {
touchInfo.dispose();
super.dispose();
}
List<Offset> _initPoints() {
final List<Offset> pos = [];
//第一段线
pos.add(Offset(0, rate) * _radius);
pos.add(Offset(1 - rate, 1) * _radius);
pos.add(Offset(1, 1) * _radius);
//第二段线
pos.add(Offset(1 + rate, 1) * _radius);
pos.add(Offset(2, rate) * _radius);
pos.add(Offset(2, 0) * _radius);
//第三段线
pos.add(Offset(2, -rate) * _radius);
pos.add(Offset(1 + rate, -1) * _radius);
pos.add(Offset(1, -1) * _radius);
//第四段线
pos.add(Offset(1 - rate, -1) * _radius);
pos.add(Offset(0, -rate) * _radius);
pos.add(Offset(0, 0));
return pos;
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder:(_,cts)=> GestureDetector(
onPanDown: (details)=>_onPanDown(details,cts.biggest),
onPanUpdate: (details)=>_onPanUpdate(details,cts.biggest),
child: Container(
color: Colors.white,
child: CustomPaint(
painter: PaperPainter(repaint: touchInfo),
),
),
),
);
}
void _onPanDown(DragDownDetails details,Size size) {
print("=====${details}===========${touchInfo.points.length}}");
if (touchInfo.points.length < 4) {
touchInfo.addPoint(details.localPosition);
} else {
judgeZone(details.localPosition,size);
}
}
void _onPanUpdate(DragUpdateDetails details,Size size) {
judgeZone(details.localPosition,size, update: true);
}
///判断出是否在某点的半径为r圆范围内
bool judgeCircleArea(Offset src, Offset dst, double r) =>
(src - dst).distance <= r;
//判断哪个点被选中
void judgeZone(Offset src, Size size,{bool update = false}) {
src= src.translate(-size.width/2, -size.height/2);
for (int i = 0; i < touchInfo.points.length; i++) {
if (judgeCircleArea(src, touchInfo.points[i], 15)) {
touchInfo.selectIndex = i;
if (update) {
touchInfo.updatePoint(i, src);
}
}
}
}
}
class PaperPainter extends CustomPainter {
final Coordinate coordinate = Coordinate();
Paint _helpPaint = Paint()
..color = Colors.purple
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
final TouchInfo repaint;
PaperPainter({required this.repaint}) : super(repaint: repaint);
List<Offset> pos = [];
@override
void paint(Canvas canvas, Size size) {
coordinate.paint(canvas, size);
canvas.translate(size.width / 2, size.height / 2);
pos = repaint.points;
Path path = Path();
Paint paint = Paint()
..color = Colors.orange
..style = PaintingStyle.stroke
..strokeWidth = 2;
path.moveTo(0, 0);
for (int i = 0; i < pos.length / 3; i++) {
path.cubicTo(pos[3 * i + 0].dx, pos[3 * i + 0].dy, pos[3 * i + 1].dx,
pos[3 * i + 1].dy, pos[3 * i + 2].dx, pos[3 * i + 2].dy);
}
canvas.drawPath(path, paint);
_drawHelp(canvas);
_drawSelectPos(canvas, size);
}
void _drawHelp(Canvas canvas) {
_helpPaint..strokeWidth = 1..color=Colors.purple;
canvas.drawLine(pos[0], pos[11], _helpPaint);
canvas.drawLine(pos[1], pos[2], _helpPaint);
canvas.drawLine(pos[2], pos[3], _helpPaint);
canvas.drawLine(pos[4], pos[5], _helpPaint);
canvas.drawLine(pos[5], pos[6], _helpPaint);
canvas.drawLine(pos[7], pos[8], _helpPaint);
canvas.drawLine(pos[8], pos[9], _helpPaint);
canvas.drawLine(pos[10], pos[11], _helpPaint);
canvas.drawLine(pos[11], pos[0], _helpPaint);
canvas.drawPoints(PointMode.points, pos, _helpPaint..strokeWidth = 8);
}
void _drawSelectPos(Canvas canvas, Size size) {
Offset? selectPos = repaint.selectPoint;
if (selectPos == null) return;
canvas.drawCircle(selectPos, 10,
_helpPaint..color = Colors.green..strokeWidth = 2);
}
@override
bool shouldRepaint(PaperPainter oldDelegate) =>
oldDelegate.repaint != repaint;
}

View File

@@ -0,0 +1,132 @@
import 'package:flutter/material.dart';
import '../components/coordinate_pro.dart';
/// create by 张风捷特烈 on 2020/5/1
/// contact me by email 1981462002@qq.com
/// 说明:
class Paper extends StatelessWidget {
const Paper({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: CustomPaint(
// 使用CustomPaint
painter: PaperPainter(),
),
);
}
}
class PaperPainter extends CustomPainter {
final Coordinate coordinate = Coordinate();
List<Offset> points1 = [
Offset(0, 20),
Offset(40, 40) ,
Offset(80, -20),
Offset(120, -40),
Offset(160, -80),
Offset(200, -20),
Offset(240, -40),
];
List<Offset> points2 = [
Offset(0, 0),
Offset(40, -20) ,
Offset(80, -40),
Offset(120, -80),
Offset(160, -40),
Offset(200, 20),
Offset(240, 40),
];
List<Offset> helpPoints = [
];
Paint _helpPaint = Paint();
Path _linePath = Path();
@override
void paint(Canvas canvas, Size size) {
coordinate.paint(canvas, size);
canvas.translate(size.width / 2, size.height / 2);
Paint paint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 1;
Path path = Path();
addBezierPathWithPoints(path, points2);
canvas.drawPath(path, paint);
addBezierPathWithPoints(_linePath, points1);
canvas.drawPath(_linePath, paint..color=Colors.orange);
_drawHelp(canvas);
}
void addBezierPathWithPoints(Path path, List<Offset> points) {
for (int i = 0; i < points.length - 1; i++) {
Offset current = points[i];
Offset next = points[i+1];
if (i == 0) {
path.moveTo(current.dx, current.dy);
// 控制点
double ctrlX = current.dx + (next.dx - current.dx) / 2;
double ctrlY = next.dy;
path.quadraticBezierTo(ctrlX, ctrlY, next.dx, next.dy);
} else if (i < points.length - 2) {
// 控制点 1
double ctrl1X = current.dx + (next.dx - current.dx) / 2;
double ctrl1Y = current.dy;
// 控制点 2
double ctrl2X = ctrl1X;
double ctrl2Y = next.dy;
path.cubicTo(ctrl1X,ctrl1Y,ctrl2X,ctrl2Y,next.dx,next.dy);
}else{
// 控制点
double ctrlX = (next.dx - current.dx) / 2;
double ctrlY = 0;
path.relativeQuadraticBezierTo(ctrlX, ctrlY, next.dx-current.dx, next.dy-current.dy);
}
}
}
void _drawHelp(Canvas canvas) {
_helpPaint
..style = PaintingStyle.stroke;
points1.forEach((element) {
canvas.drawCircle(element, 2, _helpPaint..strokeWidth=1..color=Colors.orange);
});
points2.forEach((element) {
canvas.drawCircle(element, 2, _helpPaint..strokeWidth=1..color=Colors.red);
});
// canvas.drawPoints(PointMode.polygon, points1, _helpPaint..strokeWidth=0.5..color=Colors.red);// _drawHelp(canvas);
// canvas.drawPoints(PointMode.polygon, points2, _helpPaint..strokeWidth=0.5..color=Colors.red);// _drawHelp(canvas);
// canvas.drawPoints(PointMode.polygon, helpPoints, _helpPaint..strokeWidth=0.5..color=Colors.red);// _drawHelp(canvas);
// _helpPaint
// ..color = Colors.purple
// ..style = PaintingStyle.stroke
// ..strokeCap = StrokeCap.round;
// canvas.drawPoints(PointMode.lines, [Offset.zero, p1, p1, p2],
// _helpPaint..strokeWidth = 1);
// canvas.drawPoints(PointMode.points, [Offset.zero, p1, p1, p2],
// _helpPaint..strokeWidth = 8);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}

View File

@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
/// create by 张风捷特烈 on 2020/11/4
/// contact me by email 1981462002@qq.com
/// 说明:
class TouchInfo extends ChangeNotifier {
List<Offset> _points = [];
int _selectIndex = -1;
void setPoints(List<Offset> points) {
_points = points;
}
int get selectIndex => _selectIndex;
List<Offset> get points => _points;
set selectIndex(int value) {
assert(value != null);
if (_selectIndex == value) return;
_selectIndex = value;
notifyListeners();
}
void addPoint(Offset point) {
points.add(point);
notifyListeners();
}
void updatePoint(int index, Offset point) {
points[index] = point;
notifyListeners();
}
void reset() {
_points.clear();
_selectIndex = -1;
notifyListeners();
}
Offset? get selectPoint => _selectIndex == -1 ? null : _points[_selectIndex];
}