首页 文章

如何在颤动中为一条路径设置动画?

提问于
浏览
2

我想在这里看到路径动画效果:

This animation (I couldn't include it because the gif is too big)

我只想在 Map 动画上实现路径,我知道我需要使用堆叠,放置我的 Map ,然后使用画家绘制这样的路径,但我该如何设置动画呢?

1 回答

  • 3

    你实际上并不需要Stack;你可以在 Map 图像上使用foregroundPainter . 要动画 CustomPainterAnimationController 传递给它的构造函数以及 super 构造函数 . 在 paint 中使用动画的 value 来决定绘制多少路径 . 例如,如果 value 为0.25,则仅绘制路径的前25% .

    class AnimatedPainter extends CustomPainter {
      final Animation<double> _animation;
    
      AnimatedPainter(this._animation) : super(repaint: _animation);
    
      @override
      void paint(Canvas canvas, Size size) {
        // _animation.value has a value between 0.0 and 1.0
        // use this to draw the first X% of the path
      }
    
      @override
      bool shouldRepaint(AnimatedPainter oldDelegate) {
        return true;
      }
    }
    
    class PainterDemo extends StatefulWidget {
      @override
      PainterDemoState createState() => new PainterDemoState();
    }
    
    class PainterDemoState extends State<PainterDemo>
        with SingleTickerProviderStateMixin {
      AnimationController _controller;
    
      @override
      void initState() {
        super.initState();
        _controller = new AnimationController(
          vsync: this,
        );
      }
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      void _startAnimation() {
        _controller.stop();
        _controller.reset();
        _controller.repeat(
          period: Duration(seconds: 5),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(title: const Text('Animated Paint')),
          body: new CustomPaint(
            foregroundPainter: new AnimatedPainter(_controller),
            child: new SizedBox(
              // doesn't have to be a SizedBox - could be the Map image
              width: 200.0,
              height: 200.0,
            ),
          ),
          floatingActionButton: new FloatingActionButton(
            onPressed: _startAnimation,
            child: new Icon(Icons.play_arrow),
          ),
        );
      }
    }
    
    void main() {
      runApp(
        new MaterialApp(
          home: new PainterDemo(),
        ),
      );
    }
    

    据推测,您将拥有一个定义路径的坐标列表 . 假设有一些点列表,你可以用以下方法绘制完整的路径:

    if (points.isEmpty) return;
    Path path = Path();
    Offset origin = points[0];
    path.moveTo(origin.dx, origin.dy);
    for (Offset o in points) {
      path.lineTo(o.dx, o.dy);
    }
    canvas.drawPath(
      path,
      Paint()
        ..color = Colors.orange
        ..style = PaintingStyle.stroke
        ..strokeWidth = 4.0,
    );
    

    value 小于1.0时,您需要设计一种方法来绘制小于100%的路径 . 例如,当值为0.25时,您可能只将第一个四分之一的点添加到路径中 . 如果你的路径由相对较少的点组成,那么如果你计算了路径的总长度,你可能会获得最流畅的动画,并且只绘制了路径的第一段,它们总计加起来总长度的四分之一 .

相关问题