问题描述
当我尝试在同一路径中渲染两个圆弧时,两个圆弧都同时渲染,但我需要在第一个圆弧的动画完成后渲染第二个圆弧。
我只想渲染第二个弧,因为它应该从第一个弧的末端开始并完成动画的其余部分(连续动画)。
预期结果 | 实际结果 |
---|---|
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Circle(),),);
}
}
class Circle extends StatefulWidget {
@override
_CircleState createState() => _CircleState();
}
class _CircleState extends State<Circle> with SingleTickerProviderStateMixin {
double? _fraction = 0.0;
late Animation<double> _animation;
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller =
AnimationController(duration: Duration(milliseconds: 5000),vsync: this);
_animation = Tween(begin: 0.0,end: 1.0).animate(_controller)
..addListener(() {
setState(() {
_fraction = _animation.value;
});
});
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Padding(
padding: const EdgeInsets.all(24.0),child: CustomPaint(
painter: CirclePainter(fraction: _fraction!),);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class CirclePainter extends CustomPainter {
final double? fraction;
late Paint _circlePaint;
CirclePainter({this.fraction}) {
_circlePaint = Paint()
..color = Colors.red
..style = PaintingStyle.fill;
}
final Paint _paint = Paint()
..color = Colors.black
..style = PaintingStyle.stroke
..strokeWidth = 3;
@override
void paint(Canvas canvas,Size size) {
final Path path = Path();
path.addArc(
Rect.fromCircle(center: Offset(size.width/2,size.height/2),radius: 131.0909090909091),_degreesToradians(-90).todouble(),(_degreesToradians(269.999 * fraction!).todouble() - _degreesToradians(-90).todouble()));
path.arcTo(
Rect.fromCircle(center: Offset(size.width/2,radius: 42.32727272727273),_degreesToradians(269.999 * fraction!).todouble(),_degreesToradians(-90).todouble() - _degreesToradians((269.999) * fraction!).todouble(),false);
path.addArc(
Rect.fromCircle(center: Offset(size.width/2,(_degreesToradians(179.999 * fraction!).todouble() - _degreesToradians(-90).todouble()));
path.arcTo(
Rect.fromCircle(center: Offset(size.width/2,_degreesToradians(179.999 * fraction!).todouble(),_degreesToradians(-90).todouble() - _degreesToradians((179.999) * fraction!).todouble(),false);
canvas.drawPath(path,_circlePaint);
canvas.drawPath(path,_paint);
}
@override
bool shouldRepaint(CirclePainter oldDelegate) {
return oldDelegate.fraction != fraction;
}
}
num _degreesToradians(num deg) => deg * (pi / 180);
预期:
解决方法
你可以这样做,第一个角是起始角,第二个角是终止角。你可以随意调整其他东西,但要获得旋转的效果,你需要不断改变结束角度。
我不想让笔尖变圆,你可以放 StrokeCap.butt
这个弧度函数的库是 vector_math。
_path.addArc(Rect.fromLTWH(0,size.width,size.height),vm.radians(-90),vm.radians(90));
canvas.drawPath(
_path,Paint()
..strokeCap = StrokeCap.round
..strokeWidth = 40
..style = PaintingStyle.stroke);
对于第二个开始,您可以再次使用与我在上面代码中编写的相同的概念,并结合交错动画。
final Animation<double> firstAnimation=
Tween<double>(begin: 0,end: 1).animate(CurvedAnimation(
parent: animationController,curve: Interval(0,0.5,curve: Curves.easeIn),));
final Animation<double> secondAnimation=
Tween<double>(begin: 0,curve: Interval(0.5,1,));