182 lines
4.9 KiB
Dart
182 lines
4.9 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:marking_app/utils/index.dart';
|
||
|
||
/// 说明: 贝塞尔曲线测试画布
|
||
class FlutterWaveLoading extends StatefulWidget {
|
||
final double width;
|
||
final double height;
|
||
final double waveHeight;
|
||
final Color color;
|
||
final double strokeWidth;
|
||
final double progress;
|
||
final double factor;
|
||
final int secondAlpha;
|
||
final double borderRadius;
|
||
final bool isOval;
|
||
final int milliseconds;
|
||
|
||
FlutterWaveLoading(
|
||
{this.width = 100,
|
||
this.height = 100 / 0.618,
|
||
this.factor = 1,
|
||
this.waveHeight = 5,
|
||
this.progress = 0.5,
|
||
this.color = Colors.green,
|
||
this.strokeWidth = 3,
|
||
this.secondAlpha = 88,
|
||
this.isOval = false,
|
||
this.milliseconds = 3000,
|
||
this.borderRadius = 20});
|
||
|
||
@override
|
||
_FlutterWaveLoadingState createState() => _FlutterWaveLoadingState();
|
||
}
|
||
|
||
class _FlutterWaveLoadingState extends State<FlutterWaveLoading> with SingleTickerProviderStateMixin {
|
||
late AnimationController _controller;
|
||
late Animation _anim;
|
||
|
||
@override
|
||
void initState() {
|
||
_controller = AnimationController(vsync: this, duration: Duration(milliseconds: widget.milliseconds))
|
||
..addListener(toSetState)
|
||
..repeat();
|
||
_anim = CurveTween(curve: Curves.linear).animate(_controller);
|
||
super.initState();
|
||
}
|
||
|
||
void toSetState() => toUpState(setState, () {}, mounted);
|
||
|
||
@override
|
||
void dispose() {
|
||
try {
|
||
_controller
|
||
..removeListener(toSetState)
|
||
..dispose();
|
||
} catch (e) {
|
||
print('报错了.........:');
|
||
print(e);
|
||
}
|
||
super.dispose();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return UnconstrainedBox(
|
||
child: Container(
|
||
width: widget.width,
|
||
height: widget.height,
|
||
child: CustomPaint(
|
||
painter: BezierPainter(
|
||
factor: _anim.value,
|
||
waveHeight: widget.waveHeight,
|
||
progress: widget.progress,
|
||
color: widget.color,
|
||
strokeWidth: widget.strokeWidth,
|
||
secondAlpha: widget.secondAlpha,
|
||
isOval: widget.isOval,
|
||
borderRadius: widget.borderRadius),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
class BezierPainter extends CustomPainter {
|
||
late Paint _mainPaint;
|
||
late Path _mainPath;
|
||
|
||
double waveWidth = 80;
|
||
late double wrapHeight;
|
||
|
||
final double waveHeight;
|
||
final Color color;
|
||
final double strokeWidth;
|
||
final double progress;
|
||
final double factor;
|
||
final int secondAlpha;
|
||
final double borderRadius;
|
||
final bool isOval;
|
||
|
||
BezierPainter(
|
||
{this.factor = 1,
|
||
this.waveHeight = 8,
|
||
this.progress = 0.5,
|
||
this.color = Colors.green,
|
||
this.strokeWidth = 3,
|
||
this.secondAlpha = 88,
|
||
this.isOval = false,
|
||
this.borderRadius = 20}) {
|
||
_mainPaint = Paint()
|
||
..color = Colors.yellow
|
||
..style = PaintingStyle.stroke
|
||
..strokeWidth = 2;
|
||
_mainPath = Path();
|
||
}
|
||
|
||
@override
|
||
void paint(Canvas canvas, Size size) {
|
||
// print(size);
|
||
waveWidth = size.width / 2;
|
||
wrapHeight = size.height;
|
||
|
||
Path path = Path();
|
||
if (!isOval) {
|
||
path.addRRect(RRect.fromRectXY(Offset(0, 0) & size, borderRadius, borderRadius));
|
||
canvas.clipPath(path);
|
||
// 边框
|
||
// canvas.drawPath(
|
||
// path,
|
||
// _mainPaint
|
||
// ..strokeWidth = strokeWidth
|
||
// ..color = color);
|
||
}
|
||
if (isOval) {
|
||
path.addOval(Offset(0, 0) & size);
|
||
canvas.clipPath(path);
|
||
canvas.drawPath(
|
||
path,
|
||
_mainPaint
|
||
..strokeWidth = strokeWidth
|
||
..color = color);
|
||
}
|
||
canvas.translate(0, wrapHeight);
|
||
canvas.save();
|
||
canvas.translate(0, waveHeight);
|
||
canvas.save();
|
||
canvas.translate(-4 * waveWidth + 2 * waveWidth * factor, 0);
|
||
drawWave(canvas);
|
||
canvas.drawPath(
|
||
_mainPath,
|
||
_mainPaint
|
||
..style = PaintingStyle.fill
|
||
..color = color.withAlpha(88));
|
||
canvas.restore();
|
||
|
||
canvas.translate(-4 * waveWidth + 2 * waveWidth * factor * 2, 0);
|
||
drawWave(canvas);
|
||
canvas.drawPath(
|
||
_mainPath,
|
||
_mainPaint
|
||
..style = PaintingStyle.fill
|
||
..color = color);
|
||
canvas.restore();
|
||
}
|
||
|
||
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(CustomPainter oldDelegate) => true;
|
||
}
|