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 'p15_page.dart';

View File

@@ -0,0 +1,29 @@
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;
import 's06.dart' as s6;
class P15Page extends StatelessWidget {
const P15Page({super.key});
@override
Widget build(BuildContext context) {
return const DemoShower(
srcCodeDir: 'draw/p15',
demos: [
s1.Paper(),
s2.Paper(),
s3.Paper(),
s4.Paper(),
s5.Paper(),
s6.Paper(),
],
);
}
}

View File

@@ -0,0 +1,68 @@
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();
Paint _helpPaint = Paint();
double waveWidth = 80;
double wrapHeight=0;
double waveHeight = 40;
@override
void paint(Canvas canvas, Size size) {
coordinate.paint(canvas, size);
canvas.translate(size.width / 2, size.height / 2);
Path path = Path();
Paint paint = Paint()
..color = Colors.orange
..style = PaintingStyle.fill
..strokeWidth = 2;
path.relativeQuadraticBezierTo( waveWidth / 2, -waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo( waveWidth / 2, waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo( waveWidth / 2, -waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo( waveWidth / 2, waveHeight * 2, waveWidth, 0);
canvas.drawPath(path, paint);
_drawHelp(canvas);
}
void _drawHelp(Canvas canvas) {
_helpPaint
..color = Colors.purple
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
canvas.drawPoints(PointMode.polygon,[Offset.zero, Offset(waveWidth / 2, -waveHeight * 2), Offset(waveWidth , 0)], _helpPaint..strokeWidth=1);
canvas.drawPoints(PointMode.points, [Offset.zero, Offset(waveWidth / 2, -waveHeight * 2), Offset(waveWidth , 0)],
_helpPaint..strokeWidth = 8);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}

View File

@@ -0,0 +1,69 @@
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();
Paint _helpPaint = Paint();
double waveWidth = 80;
double wrapHeight =100;
double waveHeight = 40;
@override
void paint(Canvas canvas, Size size) {
coordinate.paint(canvas, size);
canvas.translate(size.width / 2, size.height / 2);
Path path = Path();
Paint paint = Paint()
..color = Colors.orange
..style = PaintingStyle.stroke
..strokeWidth = 2;
canvas.save();
canvas.translate(-2*waveWidth, 0);
path.moveTo(0, 0);
path.relativeQuadraticBezierTo(waveWidth/2, -waveHeight*2, waveWidth, 0);
path.relativeQuadraticBezierTo(waveWidth/2, waveHeight*2, waveWidth, 0);
path.relativeQuadraticBezierTo(waveWidth/2, -waveHeight*2, waveWidth, 0);
path.relativeQuadraticBezierTo(waveWidth/2, waveHeight*2, waveWidth, 0);
path.close();
canvas.drawPath(path, paint..style=PaintingStyle.fill);
canvas.restore();
_drawHelp(canvas);
}
void _drawHelp(Canvas canvas) {
_helpPaint
..color = Colors.purple
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
canvas.drawRect(Rect.fromPoints(Offset(0,-100), Offset(160,100)), _helpPaint..strokeWidth=2);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}

View File

@@ -0,0 +1,96 @@
import 'package:flutter/material.dart';
import '../components/coordinate_pro.dart';
class Paper extends StatefulWidget {
const Paper({super.key});
@override
_PaperState createState() => _PaperState();
}
class _PaperState extends State<Paper> with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 500),
vsync: this,
)..repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: CustomPaint(
painter: PaperPainter(_controller),
),
);
}
}
class PaperPainter extends CustomPainter {
final Coordinate coordinate = Coordinate();
Paint _helpPaint = Paint();
final Animation<double> repaint;
PaperPainter(this.repaint) : super(repaint: repaint);
double waveWidth = 80;
double wrapHeight = 100;
double waveHeight = 20;
@override
void paint(Canvas canvas, Size size) {
coordinate.paint(canvas, size);
canvas.translate(size.width / 2, size.height / 2);
Path path = Path();
Paint paint = Paint()
..color = Colors.orange
..style = PaintingStyle.stroke
..strokeWidth = 2;
canvas.save();
// canvas.translate(-2*waveWidth, 0);
canvas.translate(-2 * waveWidth + 2 * waveWidth * repaint.value, 0);
path.moveTo(0, 0);
path.relativeQuadraticBezierTo(
waveWidth / 2, -waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo(waveWidth / 2, waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo(
waveWidth / 2, -waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo(waveWidth / 2, waveHeight * 2, waveWidth, 0);
path.relativeLineTo(0, wrapHeight);
path.relativeLineTo(-waveWidth * 2 * 2.0, 0);
path.close();
canvas.drawPath(path, paint..style = PaintingStyle.fill);
canvas.restore();
_drawHelp(canvas);
}
void _drawHelp(Canvas canvas) {
_helpPaint
..color = Colors.purple
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
canvas.drawRect(Rect.fromPoints(Offset(0, -100), Offset(160, 100)),
_helpPaint..strokeWidth = 2);
}
@override
bool shouldRepaint(PaperPainter oldDelegate) =>
oldDelegate.repaint != repaint;
}

View File

@@ -0,0 +1,106 @@
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> with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 500),
vsync: this,
)..repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: CustomPaint(
painter: PaperPainter(CurveTween(curve: Curves.easeInOutQuad).animate(_controller)),
),
);
}
}
class PaperPainter extends CustomPainter {
final Coordinate coordinate = Coordinate();
Paint _helpPaint = Paint();
final Animation<double> repaint;
PaperPainter(this.repaint) : super(repaint: repaint);
double waveWidth = 80;
double wrapHeight = 100;
double waveHeight = 20;
@override
void paint(Canvas canvas, Size size) {
coordinate.paint(canvas, size);
canvas.translate(size.width / 2, size.height / 2);
canvas.clipRect((Rect.fromCenter(
center: Offset( waveWidth, 0),width: waveWidth*2,height: 200.0)));
Path path = Path();
Paint paint = Paint()
..color = Colors.orange
..style = PaintingStyle.stroke
..strokeWidth = 2;
canvas.save();
// canvas.translate(-2*waveWidth, 0);
canvas.translate(-2 * waveWidth + 2 * waveWidth * repaint.value, 0);
path.moveTo(0, 0);
path.relativeQuadraticBezierTo(
waveWidth / 2, -waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo(waveWidth / 2, waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo(
waveWidth / 2, -waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo(waveWidth / 2, waveHeight * 2, waveWidth, 0);
path.relativeLineTo(0, wrapHeight);
path.relativeLineTo(-waveWidth * 2 * 2.0, 0);
path.close();
canvas.drawPath(path, paint..style = PaintingStyle.fill);
canvas.restore();
_drawHelp(canvas);
}
void _drawHelp(Canvas canvas) {
_helpPaint
..color = Colors.purple
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
canvas.drawRect(Rect.fromPoints(Offset(0, -100), Offset(160, 100)),
_helpPaint..strokeWidth = 2);
}
@override
bool shouldRepaint(PaperPainter oldDelegate) =>
oldDelegate.repaint != repaint;
}

View File

@@ -0,0 +1,97 @@
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 StatefulWidget {
const Paper({super.key});
@override
_PaperState createState() => _PaperState();
}
class _PaperState extends State<Paper> with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 1000),
vsync: this,
)
..repeat()
;
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: CustomPaint(
painter: PaperPainter(
CurveTween(curve: Curves.linear).animate(_controller)),
),
);
}
}
class PaperPainter extends CustomPainter {
final Animation<double> repaint;
PaperPainter(this.repaint) : super(repaint: repaint);
double waveWidth = 80;
double wrapHeight = 100;
double waveHeight = 10;
@override
void paint(Canvas canvas, Size size) {
canvas.translate(size.width / 2, size.height / 2);
canvas.clipRect((Rect.fromCenter(
center: Offset(waveWidth, 0), width: waveWidth * 2, height: 200.0)));
Paint paint = Paint();
Path path = getWavePath();
canvas.translate(-4 * waveWidth + 2 * waveWidth * repaint.value, 0);
canvas.drawPath(path, paint..color = Colors.orange);
canvas.translate(2*waveWidth* repaint.value, 0);
canvas.drawPath(path, paint..color = Colors.orange.withAlpha(88));
}
Path getWavePath() {
Path path = Path();
path.relativeQuadraticBezierTo(
waveWidth / 2, -waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo(
waveWidth / 2, waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo(
waveWidth / 2, -waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo(
waveWidth / 2, waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo(
waveWidth / 2, -waveHeight * 2, waveWidth, 0);
path.relativeQuadraticBezierTo(
waveWidth / 2, waveHeight * 2, waveWidth, 0);
path.relativeLineTo(0, wrapHeight);
path.relativeLineTo(-waveWidth * 3 * 2.0, 0);
return path;
}
@override
bool shouldRepaint(PaperPainter oldDelegate) =>
oldDelegate.repaint != repaint;
}

View File

@@ -0,0 +1,192 @@
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 Center(child: Wrap(
spacing: 30,
runSpacing: 30,
children: List.generate(12, (v) => 0.1 * v+0.1)
.map((e) => TolyWaveLoading(
isOval: (e*10).toInt().isEven, // 是否椭圆裁切
progress: 0.5, // 进度
waveHeight: 3, //波浪高
color: [Colors.blue,Colors.red,Colors.green][(e*10).toInt()%3], //颜色
)).toList(),
),
);
}
}
class TolyWaveLoading extends StatefulWidget {
// 波高
final double waveHeight;
// 进度
final double progress;
// 颜色
final Color color;
// 尺寸
final Size size;
// 底波透明度
final int secondAlpha;
// 边线宽
final double strokeWidth;
// 圆角半径
final double borderRadius;
// 是否是椭圆
final bool isOval;
final Duration duration;
final Curve curve;
const TolyWaveLoading(
{Key? key,
this.waveHeight = 5,
this.progress = 0.5,
this.duration = const Duration(seconds: 1),
this.size = const Size(100, 100),
this.color = Colors.green,
this.secondAlpha = 88,
this.strokeWidth = 3,
this.curve = Curves.linear,
this.borderRadius = 20,
this.isOval = false})
: super(key: key);
@override
_TolyWaveLoadingState createState() => _TolyWaveLoadingState();
}
class _TolyWaveLoadingState extends State<TolyWaveLoading>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: widget.duration,
vsync: this,
)..repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return CustomPaint(
size: widget.size,
painter: PaperPainter(
waveHeight: widget.waveHeight,
secondAlpha: widget.secondAlpha,
color: widget.color,
borderRadius: widget.borderRadius,
isOval: widget.isOval,
progress: widget.progress,
strokeWidth: widget.strokeWidth,
repaint: CurveTween(curve: widget.curve).animate(_controller)),
);
}
}
class PaperPainter extends CustomPainter {
final Animation<double> repaint;
PaperPainter({
required this.repaint,
required this.waveHeight,
required this.color,
required this.progress,
required this.secondAlpha,
required this.borderRadius,
required this.isOval,
required this.strokeWidth,
}) : super(repaint: repaint);
final double waveHeight;
final double progress;
final Color color;
final double strokeWidth;
final int secondAlpha;
final double borderRadius;
final bool isOval;
Path path = Path();
Paint _mainPaint = Paint();
Path _mainPath = Path();
double waveWidth = 0;
double wrapHeight = 0;
@override
void paint(Canvas canvas, Size size) {
// 由于 使用 repaint 触发更新 path 和 _mainPath 不会重新创建
// 而导致刷新时不断为 path 和 _mainPath 添加路径,导致路径非常庞大,越来越卡,而掉帧
// 处理方案一: 绘制前 重置 path 或者
// 处理方案二: 不将 path 设为成员变量,每次绘制都新建 Path 对象,这样会造成大量 Path 对象创建,测试发现两种方案结果差不多。
path.reset();
_mainPath.reset();
waveWidth = size.width / 2;
wrapHeight = size.height;
_mainPaint..strokeWidth = strokeWidth..style = PaintingStyle.stroke..color = color;
if (!isOval) {
path.addRRect(RRect.fromRectXY(Offset(0, 0) & size, borderRadius, borderRadius));
canvas.clipPath(path);
canvas.drawPath(path,_mainPaint);
}
if (isOval) {
path.addOval(Offset(0, 0) & size);
canvas.clipPath(path);
canvas.drawPath(path, _mainPaint);
}
canvas.translate(-4 * waveWidth + 2 * waveWidth * repaint.value, wrapHeight + waveHeight);
drawWave(canvas);
canvas.drawPath(_mainPath, _mainPaint..style = PaintingStyle.fill..color = color);
canvas.translate(2 * waveWidth * repaint.value, 0);
drawWave(canvas);
canvas.drawPath(_mainPath, _mainPaint..color = color.withAlpha(88));
}
void drawWave(Canvas canvas) {
_mainPath.moveTo(0, 0);
_mainPath.relativeLineTo(0, -wrapHeight * progress);
_mainPath.relativeQuadraticBezierTo(waveWidth / 2, -waveHeight * 2, waveWidth, 0);
_mainPath.relativeQuadraticBezierTo(waveWidth / 2, waveHeight * 2, waveWidth, 0);
_mainPath.relativeQuadraticBezierTo(waveWidth / 2, -waveHeight * 2, waveWidth, 0);
_mainPath.relativeQuadraticBezierTo(waveWidth / 2, waveHeight * 2, waveWidth, 0);
_mainPath.relativeQuadraticBezierTo(waveWidth / 2, -waveHeight * 2, waveWidth, 0);
_mainPath.relativeQuadraticBezierTo(waveWidth / 2, waveHeight * 2, waveWidth, 0);
_mainPath.relativeLineTo(0, wrapHeight);
_mainPath.relativeLineTo(-waveWidth * 3 * 2.0, 0);
}
@override
bool shouldRepaint(PaperPainter oldDelegate) =>
oldDelegate.repaint != repaint|| oldDelegate.waveHeight != waveHeight||
oldDelegate.progress != progress|| oldDelegate.color != color||
oldDelegate.strokeWidth != strokeWidth|| oldDelegate.isOval != isOval||
oldDelegate.secondAlpha != secondAlpha|| oldDelegate.borderRadius != borderRadius;
}

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];
}