一个带有动画的连线

207 阅读1分钟

动画对于App来说,非常的重要。很多App,正是因为有了动画,所以才会觉得炫酷。今天就实现一个简单连线动画。

继承与CustomPainter的画笔

通过list传入数据后,将画笔的起始点放在(0,0)的位置之后用画笔画出与其他位置的连线。


class MyPaint extends CustomPainter {
List<Size> animationSize;
MyPaint(this.animationSize);
@override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
Paint paint = Paint()
..style = PaintingStyle.stroke
..color = Colors.black
..strokeWidth = 1;
Path path = Path();
path.moveTo(0, 0);
animationSize.forEach((element) {
path.lineTo(element.width, element.height);
});

canvas.drawPath(path, paint);
}

@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}

动画的实现

1、初始化一个位置的存储队列后,在画布的点击事件中将点击位置添加入队列。 2、在点击事件中完成动画的创建,并把位置队列的末尾元素添加为动画的结束值,如果位置队列的长度大于1则吧倒数第二个元素添加为动画的起始值。 3.这样就能获得一个由结尾的一个点向新的结尾点的动画值,用新的动画的值替换位置队列中的最后一位。

class PaintBG extends StatefulWidget {
  @override
  _PaintBGState createState() => _PaintBGState();
}

class _PaintBGState extends State<PaintBG> with TickerProviderStateMixin {
  Animation<Size> _animation;
  AnimationController _animationController;
  List<Size> _pathSizeList;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _pathSizeList = [];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTapDown: (details) {
          setState(() {
            _pathSizeList.add(
                Size(details.globalPosition.dx, details.globalPosition.dy));
          });
          _animationController =
              AnimationController(vsync: this, duration: Duration(seconds: 1))
                ..addListener(() {
                  setState(() {
                    print(_animation.value);
                    _pathSizeList.last = _animation.value;
                  });
                });
          if (_pathSizeList.length == 1) {
            _animation = Tween<Size>(begin: Size(0, 0), end: _pathSizeList.last)
                .animate(_animationController);
          } else {
            _animation = Tween<Size>(
                    begin: _pathSizeList[_pathSizeList.length - 2],
                    end: _pathSizeList.last)
                .animate(_animationController);
          }

          _pathSizeList.last = _animation.value;
          _animationController.forward();
        },
        child: Container(
          width: double.infinity,
          height: double.infinity,
          child: CustomPaint(
            painter: MyPaint(_pathSizeList),
          ),
        ),
      ),
    );
  }
}

画个有瑕疵五角星

思考

这个效果可以用在动态的数据折线图中,只不过是有我们手动的新建数据变为已经有了固定数据。