11import 'dart:ui' as ui;
22import 'package:flutter/material.dart' ;
33import 'package:flutter_text_decorator/src/modules/underline/base/underline_painter.dart' ;
4+ import 'package:flutter_text_decorator/src/modules/underline/mixins/line_gap_mixin.dart' ;
45
56/// A [CustomPainter] that draws a curved or wavy underline beneath text.
67///
@@ -29,12 +30,12 @@ import 'package:flutter_text_decorator/src/modules/underline/base/underline_pain
2930/// ),
3031/// )
3132/// ```
32- class CurvedUnderlinePainter extends UnderlinePainter {
33+ class CurvedUnderlinePainter extends UnderlinePainter with LineGap {
3334 CurvedUnderlinePainter ({
3435 required this .text,
3536 required super .color,
3637 required super .strokeWidth,
37- this .curvyFactor = 0.7 ,
38+ this .curvyFactor = 3 ,
3839 super .textStyle,
3940 });
4041
@@ -43,58 +44,44 @@ class CurvedUnderlinePainter extends UnderlinePainter {
4344
4445 @override
4546 void paint (Canvas canvas, Size size) {
46- final currentTextStyle = super .textStyle ?? const TextStyle ();
47- final textSpan = TextSpan (text: text, style: currentTextStyle);
4847 final textPainter = TextPainter (
49- text: textSpan ,
48+ text: TextSpan (text : text, style : textStyle ?? const TextStyle ()) ,
5049 textDirection: ui.TextDirection .ltr,
5150 )..layout (maxWidth: size.width);
5251
53- final Paint paint = Paint ()
54- ..color = super . color
52+ final paint = Paint ()
53+ ..color = color
5554 ..style = PaintingStyle .stroke
56- ..strokeWidth = super . strokeWidth;
55+ ..strokeWidth = strokeWidth;
5756
58- final List <ui. LineMetrics > lines = textPainter.computeLineMetrics ();
57+ final lines = textPainter.computeLineMetrics ();
5958
60- final double waveHeightUnit = super .strokeWidth * 3. 0 ;
59+ double yOffset = 0 ;
6160
62- for (int lineIdx = 0 ; lineIdx < lines.length; lineIdx++ ) {
63- final line = lines[lineIdx];
61+ for (final line in lines) {
62+ final double startX = line.left;
63+ final double xEnd = startX + line.width;
6464
65- final double startX = line.left + horizontalOffset.left;
66- final double xEnd = line.left + line.width - horizontalOffset.right;
67- final double effectiveLineWidth = xEnd - startX;
65+ if (line.width <= 0 ) continue ;
6866
69- if (effectiveLineWidth <= 0 ) {
70- continue ;
71- }
67+ yOffset += calculateGapBetweenLines (line: line, lineIndex: line.lineNumber, strokeWidth: strokeWidth);
7268
73- final double lineGapY = _calculateGapBetweenLines (lineIdx, line, super .strokeWidth);
74- final double yCp1 = lineGapY - waveHeightUnit * curvyFactor;
75- final double yCp2 = lineGapY + waveHeightUnit * curvyFactor;
76- final double yEnd = lineGapY;
77- final double xCp1 = startX + effectiveLineWidth * (1 / 3 );
78- final double xCp2 = startX + effectiveLineWidth * (2 / 3 );
69+ final double y1 = yOffset - strokeWidth * curvyFactor;
70+ final double y2 = yOffset + strokeWidth * curvyFactor;
71+ final double yEnd = yOffset;
72+ final double x1 = startX + xEnd * (1 / 3 );
73+ final double x2 = startX + xEnd * (2 / 3 );
74+ final double x3 = xEnd;
75+ final double y3 = yEnd;
7976
8077 final Path path = Path ()
81- ..moveTo (startX, lineGapY )
82- ..cubicTo (xCp1, yCp1, xCp2, yCp2, xEnd, yEnd );
78+ ..moveTo (startX, yOffset )
79+ ..cubicTo (x1, y1, x2, y2, x3, y3 );
8380
8481 canvas.drawPath (path, paint);
8582 }
8683 }
8784
88- double _calculateGapBetweenLines (int lineIndex, ui.LineMetrics line, double currentStrokeWidth) {
89- double desiredGap = 5 ;
90- if (lineIndex == 0 ) {
91- desiredGap = 1 ;
92- }
93- return line.baseline + line.descent + desiredGap + (currentStrokeWidth / 2.0 );
94- }
95-
9685 @override
97- bool shouldRepaint (covariant CustomPainter oldDelegate) {
98- return false ;
99- }
86+ bool shouldRepaint (covariant CustomPainter oldDelegate) => false ;
10087}
0 commit comments