doPaint method
Implementation
@override
void doPaint(PaintingContext context, Offset offset) {
const Curve curve = Curves.easeIn;
final progress = curve.transform(this.progress);
Rect rect = offset & size;
final paint = Paint()
..isAntiAlias = true
..style = outline ? PaintingStyle.stroke : PaintingStyle.fill //填充
..color = color;
if (outline) {
paint.strokeWidth = strokeWidth;
rect = rect.deflate(strokeWidth / 2);
}
// 画背景圆
context.canvas.drawCircle(rect.center, rect.shortestSide / 2, paint);
paint
..style = PaintingStyle.stroke
..color = outline ? color : Colors.white
..strokeWidth = strokeWidth;
final path = Path();
final Offset firstOffset =
Offset(rect.left + rect.width / 6, rect.top + rect.height / 2.1);
final secondOffset = Offset(
rect.left + rect.width / 2.5,
rect.bottom - rect.height / 3.3,
);
path.moveTo(firstOffset.dx, firstOffset.dy);
const adjustProgress = .6;
//画 "勾"
if (_progress < adjustProgress) {
//第一个点到第二个点的连线做动画(第二个点不停的变)
final Offset betweenOffset = Offset.lerp(
firstOffset,
secondOffset,
_progress / adjustProgress,
)!;
path.lineTo(betweenOffset.dx, betweenOffset.dy);
} else {
//链接第一个点和第二个点
path.lineTo(secondOffset.dx, secondOffset.dy);
//第三个点位置随着动画变,做动画
final lastOffset = Offset(
rect.right - rect.width / 5,
rect.top + rect.height / 3.5,
);
final Offset lerpOffset = Offset.lerp(
secondOffset,
lastOffset,
(progress - adjustProgress) / (1 - adjustProgress),
)!;
path.lineTo(lerpOffset.dx, lerpOffset.dy);
}
context.canvas.drawPath(path, paint..style = PaintingStyle.stroke);
}