Commit 7ee5ba32432c3f55317b729fce894c63fdc08765

Authored by 常守达
1 parent a039c9c7

fix(today):合环进度

@@ -422,27 +422,20 @@ class _UnlockPremiumCard extends StatelessWidget { @@ -422,27 +422,20 @@ class _UnlockPremiumCard extends StatelessWidget {
422 child: Row( 422 child: Row(
423 mainAxisSize: MainAxisSize.min, 423 mainAxisSize: MainAxisSize.min,
424 mainAxisAlignment: MainAxisAlignment.center, 424 mainAxisAlignment: MainAxisAlignment.center,
425 - crossAxisAlignment: CrossAxisAlignment.center, 425 + spacing: 4,
426 children: [ 426 children: [
427 - Row(  
428 - mainAxisSize: MainAxisSize.min,  
429 - mainAxisAlignment: MainAxisAlignment.start,  
430 - crossAxisAlignment: CrossAxisAlignment.center,  
431 - spacing: 4,  
432 - children: [  
433 - Image.asset('assets/images/common/ic_pro.png',  
434 - width: 18,  
435 - height: 18,  
436 - color: context.colors.textPrimary),  
437 - Text(  
438 - l10n.unlockNow,  
439 - style: TextStyle(  
440 - color: context.colors.textPrimary,  
441 - fontSize: 14,  
442 - fontWeight: FontWeight.w500,  
443 - ),  
444 - ),  
445 - ], 427 + Image.asset('assets/images/common/ic_pro.png',
  428 + width: 18,
  429 + height: 18,
  430 + color: context.colors.textPrimary),
  431 + Text(
  432 + l10n.unlockNow,
  433 + style: TextStyle(
  434 + color: context.colors.textPrimary,
  435 + fontSize: 14,
  436 + fontWeight: FontWeight.w500,
  437 + height: 1.0,
  438 + ),
446 ), 439 ),
447 ], 440 ],
448 ), 441 ),
@@ -53,27 +53,6 @@ class ProgressPainter extends CustomPainter { @@ -53,27 +53,6 @@ class ProgressPainter extends CustomPainter {
53 width: wh - strokeWidth, 53 width: wh - strokeWidth,
54 height: wh - strokeWidth, 54 height: wh - strokeWidth,
55 ); 55 );
56 - int colorRangeIndex = (sweepAngle / 360).ceil() - 1;  
57 - if (colorRangeIndex > progressColor.length - 1) {  
58 - colorRangeIndex = progressColor.length - 1;  
59 - }  
60 - if (colorRangeIndex < 0) {  
61 - colorRangeIndex = 0;  
62 - }  
63 -  
64 - var shader = SweepGradient(  
65 - startAngle: 0.toRadians(),  
66 - endAngle: 360.toRadians(),  
67 - colors: reverse  
68 - ? progressColor[colorRangeIndex].reversed.toList()  
69 - : progressColor[colorRangeIndex],  
70 - ).createShader(rect);  
71 -  
72 - var paint = Paint()  
73 - ..strokeWidth = strokeWidth  
74 - ..shader = shader  
75 - ..strokeCap = StrokeCap.butt  
76 - ..style = PaintingStyle.stroke;  
77 56
78 var backgroundPaint = Paint() 57 var backgroundPaint = Paint()
79 ..strokeWidth = strokeWidth 58 ..strokeWidth = strokeWidth
@@ -89,49 +68,93 @@ class ProgressPainter extends CustomPainter { @@ -89,49 +68,93 @@ class ProgressPainter extends CustomPainter {
89 backgroundPaint, 68 backgroundPaint,
90 ); 69 );
91 70
92 - if (sweepAngle >= 0) { 71 + if (sweepAngle > 0) {
93 double capAngle = 0; 72 double capAngle = 0;
94 if (radius > 0) { 73 if (radius > 0) {
95 capAngle = asin((strokeWidth / 2) / radius) * 180 / pi; 74 capAngle = asin((strokeWidth / 2) / radius) * 180 / pi;
96 } 75 }
97 76
98 - double actualCapAngle = capAngle;  
99 - if (sweepAngle < 360) {  
100 - if (sweepAngle < 2 * capAngle) {  
101 - actualCapAngle = sweepAngle / 2; 77 + int fullLaps = (sweepAngle / 360).floor();
  78 + double remainingAngle = sweepAngle % 360;
  79 +
  80 + // Draw full laps first
  81 + for (int i = 0; i < fullLaps; i++) {
  82 + int colorIdx = i;
  83 + if (colorIdx > progressColor.length - 1) {
  84 + colorIdx = progressColor.length - 1;
102 } 85 }
103 - } else {  
104 - actualCapAngle = 0; 86 + var shader = SweepGradient(
  87 + startAngle: 0.toRadians(),
  88 + endAngle: 360.toRadians(),
  89 + colors: reverse
  90 + ? progressColor[colorIdx].reversed.toList()
  91 + : progressColor[colorIdx],
  92 + ).createShader(rect);
  93 +
  94 + var lapPaint = Paint()
  95 + ..strokeWidth = strokeWidth
  96 + ..shader = shader
  97 + ..strokeCap = StrokeCap.butt
  98 + ..style = PaintingStyle.stroke;
  99 +
  100 + canvas.save();
  101 + canvas.translate(centerX, centerY);
  102 + canvas.rotate((-90).toRadians());
  103 + canvas.translate(-centerX, -centerY);
  104 +
  105 + canvas.drawArc(
  106 + rect,
  107 + 0.toRadians(),
  108 + reverse ? -360.toRadians() : 360.toRadians(),
  109 + false,
  110 + lapPaint,
  111 + );
  112 +
  113 + canvas.restore();
105 } 114 }
106 115
107 - double startAngle = actualCapAngle;  
108 - double drawnSweepAngle = sweepAngle;  
109 - if (sweepAngle < 360) {  
110 - drawnSweepAngle = sweepAngle - 2 * actualCapAngle; 116 + // Draw the remaining fractional lap
  117 + if (remainingAngle > 0.0) {
  118 + int colorIdx = fullLaps;
  119 + if (colorIdx > progressColor.length - 1) {
  120 + colorIdx = progressColor.length - 1;
  121 + }
  122 +
  123 + var shader = SweepGradient(
  124 + startAngle: 0.toRadians(),
  125 + endAngle: 360.toRadians(),
  126 + colors: reverse
  127 + ? progressColor[colorIdx].reversed.toList()
  128 + : progressColor[colorIdx],
  129 + ).createShader(rect);
  130 +
  131 + var lapPaint = Paint()
  132 + ..strokeWidth = strokeWidth
  133 + ..shader = shader
  134 + ..strokeCap = StrokeCap.butt
  135 + ..style = PaintingStyle.stroke;
  136 +
  137 + double actualCapAngle = capAngle;
  138 + if (remainingAngle < 2 * capAngle) {
  139 + actualCapAngle = remainingAngle / 2;
  140 + }
  141 +
  142 + double startAngle = actualCapAngle;
  143 + double drawnSweepAngle = remainingAngle - 2 * actualCapAngle;
111 if (drawnSweepAngle < 0) { 144 if (drawnSweepAngle < 0) {
112 drawnSweepAngle = 0; 145 drawnSweepAngle = 0;
113 } 146 }
114 - }  
115 147
116 - canvas.save();  
117 - // Move the canvas origin to the center  
118 - canvas.translate(centerX, centerY);  
119 - double rotationAngle = 0; 148 + canvas.save();
  149 + canvas.translate(centerX, centerY);
  150 + canvas.rotate((-90).toRadians());
  151 + canvas.translate(-centerX, -centerY);
120 152
121 - if (sweepAngle > 360) {  
122 - rotationAngle = 360 - sweepAngle;  
123 - }  
124 - double rotationRadians =  
125 - reverse ? -rotationAngle.toRadians() : rotationAngle.toRadians();  
126 - // Rotate the canvas  
127 - canvas.rotate((-90).toRadians() - rotationRadians);  
128 - // Move the canvas origin back  
129 - canvas.translate(-centerX, -centerY);  
130 -  
131 - if (sweepAngle < 360) { 153 + // Draw start cap for this fractional lap
132 canvas.save(); 154 canvas.save();
133 canvas.translate(centerX, centerY); 155 canvas.translate(centerX, centerY);
134 - canvas.rotate(reverse ? -startAngle.toRadians() : startAngle.toRadians()); 156 + canvas
  157 + .rotate(reverse ? -startAngle.toRadians() : startAngle.toRadians());
135 canvas.drawArc( 158 canvas.drawArc(
136 Rect.fromCenter( 159 Rect.fromCenter(
137 center: Offset(radius, 0), 160 center: Offset(radius, 0),
@@ -141,7 +164,10 @@ class ProgressPainter extends CustomPainter { @@ -141,7 +164,10 @@ class ProgressPainter extends CustomPainter {
141 0, 164 0,
142 reverse ? 180.toRadians() : -180.toRadians(), 165 reverse ? 180.toRadians() : -180.toRadians(),
143 true, 166 true,
144 - Paint()..color = progressColor[0].first, 167 + Paint()
  168 + ..color = reverse
  169 + ? progressColor[colorIdx].last
  170 + : progressColor[colorIdx].first,
145 ); 171 );
146 canvas.drawRect( 172 canvas.drawRect(
147 Rect.fromCenter( 173 Rect.fromCenter(
@@ -149,31 +175,37 @@ class ProgressPainter extends CustomPainter { @@ -149,31 +175,37 @@ class ProgressPainter extends CustomPainter {
149 width: strokeWidth, 175 width: strokeWidth,
150 height: 1, 176 height: 1,
151 ), 177 ),
152 - Paint()..color = progressColor[0].first, 178 + Paint()
  179 + ..color = reverse
  180 + ? progressColor[colorIdx].last
  181 + : progressColor[colorIdx].first,
153 ); 182 );
154 canvas.restore(); 183 canvas.restore();
155 - }  
156 184
157 - canvas.drawArc(  
158 - rect,  
159 - reverse ? -startAngle.toRadians() : startAngle.toRadians(),  
160 - reverse  
161 - ? -drawnSweepAngle.toRadians()  
162 - : drawnSweepAngle.toRadians(),  
163 - false,  
164 - paint,  
165 - );  
166 -  
167 - if (sweepAngle != 360) { 185 + // Draw the fractional arc
  186 + canvas.drawArc(
  187 + rect,
  188 + reverse ? -startAngle.toRadians() : startAngle.toRadians(),
  189 + reverse ? -drawnSweepAngle.toRadians() : drawnSweepAngle.toRadians(),
  190 + false,
  191 + lapPaint,
  192 + );
  193 +
  194 + // Draw end cap for this fractional lap
168 final endAngle = startAngle + drawnSweepAngle; 195 final endAngle = startAngle + drawnSweepAngle;
169 canvas.save(); 196 canvas.save();
170 canvas.translate(centerX, centerY); 197 canvas.translate(centerX, centerY);
171 canvas.rotate(reverse ? -endAngle.toRadians() : endAngle.toRadians()); 198 canvas.rotate(reverse ? -endAngle.toRadians() : endAngle.toRadians());
172 199
173 - final endColor =  
174 - getColorAtAngle(sweepAngle, progressColor[colorRangeIndex]);  
175 -  
176 - final bool shouldDrawShadow = sweepAngle > 360 || (sweepAngle > 355 && sweepAngle < 360); 200 + final endColor = getColorAtAngleOf360(
  201 + remainingAngle,
  202 + reverse
  203 + ? progressColor[colorIdx].reversed.toList()
  204 + : progressColor[colorIdx],
  205 + );
  206 +
  207 + final bool shouldDrawShadow =
  208 + sweepAngle > 360 || (remainingAngle > 355 && remainingAngle < 360);
177 if (shouldDrawShadow) { 209 if (shouldDrawShadow) {
178 //Draw arc shadow 210 //Draw arc shadow
179 var shadowPosition = Offset( 211 var shadowPosition = Offset(
@@ -208,10 +240,9 @@ class ProgressPainter extends CustomPainter { @@ -208,10 +240,9 @@ class ProgressPainter extends CustomPainter {
208 Paint()..color = endColor, 240 Paint()..color = endColor,
209 ); 241 );
210 canvas.restore(); 242 canvas.restore();
211 - }  
212 243
213 - // // Restore the canvas to the saved state  
214 - canvas.restore(); 244 + canvas.restore();
  245 + }
215 } 246 }
216 } 247 }
217 248
@@ -220,16 +251,19 @@ class ProgressPainter extends CustomPainter { @@ -220,16 +251,19 @@ class ProgressPainter extends CustomPainter {
220 return sweepAngle != oldDelegate.sweepAngle; 251 return sweepAngle != oldDelegate.sweepAngle;
221 } 252 }
222 253
223 - /// get color by and angle  
224 - Color getColorAtAngle(double angle, List<Color> colors) {  
225 - double totalAngle = sweepAngle > 360 ? sweepAngle : 360;  
226 - double fraction = angle / totalAngle; 254 + /// get color by angle of a single 360 degree span
  255 + Color getColorAtAngleOf360(double angle, List<Color> colors) {
  256 + double fraction = angle / 360.0;
  257 + if (fraction > 1.0) fraction = 1.0;
  258 + if (fraction < 0.0) fraction = 0.0;
227 int segments = colors.length - 1; 259 int segments = colors.length - 1;
  260 + if (segments <= 0) return colors.first;
228 double segmentFraction = fraction * segments; 261 double segmentFraction = fraction * segments;
229 int segmentIndex = segmentFraction.floor(); 262 int segmentIndex = segmentFraction.floor();
  263 + if (segmentIndex >= segments) segmentIndex = segments - 1;
230 double segmentInnerFraction = segmentFraction - segmentIndex; 264 double segmentInnerFraction = segmentFraction - segmentIndex;
231 Color startColor = colors[segmentIndex]; 265 Color startColor = colors[segmentIndex];
232 - Color endColor = colors[(segmentIndex + 1) % colors.length]; 266 + Color endColor = colors[segmentIndex + 1];
233 return Color.lerp(startColor, endColor, segmentInnerFraction)!; 267 return Color.lerp(startColor, endColor, segmentInnerFraction)!;
234 } 268 }
235 } 269 }