My code as of now:
class RoundedRectanglePainter extends CustomPainter {
final Color strokeColorGradientStart;
final Color strokeColorGradientEnd;
final double strokeWidth;
final double borderRadius;
final Color fillColorGradientStart;
final Color fillColorGradientEnd;
final Animation<double> animation;
RoundedRectanglePainter({
required this.strokeColorGradientStart,
required this.strokeColorGradientEnd,
required this.strokeWidth,
required this.borderRadius,
required this.fillColorGradientStart,
required this.fillColorGradientEnd,
required this.animation,
}) : super(repaint: animation);
@override
void paint(Canvas canvas, Size size) {
final strokeGradient = LinearGradient(
colors: [strokeColorGradientStart, strokeColorGradientEnd],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
final fillGradient = LinearGradient(
colors: [fillColorGradientStart, fillColorGradientEnd],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
);
final strokePaint = Paint()
..shader = strokeGradient
.createShader(Rect.fromLTWH(0, 0, size.width, size.height))
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke;
final fillPaint = Paint()
..shader = fillGradient
.createShader(Rect.fromLTWH(0, 0, size.width, size.height))
..style = PaintingStyle.fill;
final outerRect = Rect.fromLTWH(0, 0, size.width, size.height);
final outerRRect =
RRect.fromRectAndRadius(outerRect, Radius.circular(borderRadius));
canvas.drawRRect(outerRRect, strokePaint);
final innerWidth = size.width - (strokeWidth * 2) - 10;
final innerHeight = size.height - (strokeWidth * 2) - 10;
final innerRect = Rect.fromLTWH((size.width - innerWidth) / 2,
(size.height - innerHeight) / 2, innerWidth, innerHeight);
final innerRRect =
RRect.fromRectAndRadius(innerRect, Radius.circular(borderRadius));
canvas.drawRRect(innerRRect, fillPaint);
Path outerPath = Path()..addRRect(outerRRect);
PathMetrics pathMetrics = outerPath.computeMetrics();
PathMetric pathMetric = pathMetrics.first;
double currentLength = pathMetric.length * animation.value;
Tangent? tangent = pathMetric.getTangentForOffset(currentLength);
if (tangent != null) {
final movingLinePaint = Paint()
..color = Colors.red
..strokeWidth = 10.0
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke;
final lineStart = tangent.position;
final lineDirection = tangent.vector;
final lineEnd = lineStart +
Offset(
lineDirection.dx * 30,
lineDirection.dy * 30,
);
canvas.drawLine(lineStart, lineEnd, movingLinePaint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
i want that the line moving should follow the exact path as the outer rectangle is defined. i tried and tested different thing but not able to get the desired behaviour. how can i proceed further to achieve the desired functionality or behaviour or some relevant code snippet which can help me progress in the code.
in the image you can see when it reaches the curved path the line moving is not following the curveness, it simply takes a turn to right. this is the problem.
2
Answers
Please try this code
instead of
pathMetric.getTangentForOffset
usepathMetric.extractPath
, notice that it has to be called twice when trying to get a sub-path at the end of the given paththe complete code (note:
timeDilation = 5;
is used just for testing, your are free to delete it):