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