【问题标题】:How to render a arc path after previous arc animation complete上一个圆弧动画完成后如何渲染圆弧路径
【发布时间】:2021-07-14 07:49:58
【问题描述】:

当我尝试在同一路径中渲染两个圆弧时,两个圆弧同时渲染,但我需要在第一个圆弧的动画完成后渲染第二个圆弧。

我只想渲染第二条弧线,因为它应该从第一条弧线的末端开始并完成动画的其余部分(连续动画)。

Expected results Actual results

我已经附上了下面的代码sn-p,谁能帮帮我。

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, size.height/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, size.height/2), radius: 131.0909090909091),
      _degreesToRadians(-90).toDouble(), (_degreesToRadians(179.999 * fraction!).toDouble() - _degreesToRadians(-90).toDouble()));
    path.arcTo(
      Rect.fromCircle(center: Offset(size.width/2, size.height/2), radius: 42.32727272727273),
     _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);

预期:

【问题讨论】:

    标签: flutter flutter-animation flutter-canvas flutter-path


    【解决方案1】:

    你可以这样做,第一个角度是开始角度,第二个角度是结束角度。您可以根据需要调整其他内容,但要获得旋转效果,您需要不断更改结束角度。

    我不想让笔尖变圆,你可以放 StrokeCap.butt

    这个弧度函数的库是vector_math。

     _path.addArc(Rect.fromLTWH(0, 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, end: 1).animate(CurvedAnimation(
          parent: animationController,
          curve: Interval(0.5, 1, curve: Curves.easeIn),
        ));
    

    【讨论】:

    • 嗨@lgniti0n 感谢您的回复,但我想将其渲染为像预期图像一样的连续路径。你能帮我解决这个问题吗?
    • 我编辑了答案,我第一次没有让你很好现在我看到你发布的GIF,我认为这会对你有所帮助,发送反馈。
    猜你喜欢
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多