美文网首页
Flutter类似于电力输送的动画

Flutter类似于电力输送的动画

作者: Tomous | 来源:发表于2023-12-07 11:39 被阅读0次

    利用flutter写了个类似于充电的动画,比如光伏板给电池充电,模仿电力输送的过程,效果如下图所示

    gif.gif

    下面直接贴出代码,属性都标注了注释,使用的时候在外面加个盒子固定宽高,然后给出每个点的坐标,内部会根据坐标的点数来判断有几根线,然后画出线的路径,进行动画模拟,可以根据项目需求来自定义点的颜色,每条路径上点的个数以及点的大小等等,

    import 'package:flutter/material.dart';
    
    class ElectricAnimated extends StatelessWidget {
      final int duration; //动画时长
      final List<Offset> path; //路径的点坐标
      const ElectricAnimated({
        super.key,
        this.duration = 5,
        required this.path,
      });
    
      @override
      Widget build(BuildContext context) {
        return Stack(
          children: List.generate(
            path.length - 1,
            (index) {
              return AnimatedDots(
                path: [
                  path[index],
                  path[index + 1],
                ],
                dotCount: 3,
                duration: Duration(
                  seconds: duration,
                ),
              );
            },
          ),
        );
      }
    }
    
    class AnimatedDots extends StatefulWidget {
      final List<Offset> path; //路径的点坐标
      final int dotCount; //每条路径上的点的个数
      final double dotSize; //点的大小
      final Duration duration;
      final Color dotColor; //点的颜色
    
      const AnimatedDots({
        Key? key,
        required this.path,
        this.dotCount = 5,
        this.dotSize = 2,
        this.duration = const Duration(seconds: 2),
        this.dotColor = Colors.white,
      }) : super(key: key);
    
      @override
      State<AnimatedDots> createState() => _AnimatedDotsState();
    }
    
    class _AnimatedDotsState extends State<AnimatedDots>
        with SingleTickerProviderStateMixin {
      late AnimationController _animationController;
      late Animation<double> _animation;
      int _currentIndex = 0;
    
      @override
      void initState() {
        super.initState();
    
        _animationController = AnimationController(
          vsync: this,
          duration: widget.duration,
        );
    
        _animation = Tween<double>(
          begin: 0,
          end: 1,
        ).animate(_animationController);
    
        _animationController.addStatusListener((status) {
          if (status == AnimationStatus.completed) {
            _currentIndex++;
            if (_currentIndex >= widget.path.length - 1) {
              _currentIndex = 0;
            }
    
            _animationController.reset();
            _animationController.forward();
          }
        });
    
        _animationController.forward();
      }
    
      @override
      void dispose() {
        _animationController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return AnimatedBuilder(
          animation: _animation,
          builder: (context, child) {
            final value = _animation.value;
            final current = widget.path[_currentIndex];
            final next = widget.path[(_currentIndex + 1) % widget.path.length];
    
            final dots = List.generate(widget.dotCount, (index) {
              final dotValue = (value + index / widget.dotCount) % 1;
              final x = current.dx + (next.dx - current.dx) * dotValue;
              final y = current.dy + (next.dy - current.dy) * dotValue;
    
              return Positioned(
                left: x - widget.dotSize / 2,
                top: y - widget.dotSize / 2,
                child: Container(
                  width: widget.dotSize,
                  height: widget.dotSize,
                  decoration: BoxDecoration(
                    color: widget.dotColor,
                    shape: BoxShape.circle,
                  ),
                ),
              );
            });
    
            return Stack(
              children: dots,
            );
          },
        );
      }
    }
    

    使用

    body: Center(
            child: Container(
              color: Colors.black,
              width: 150,
              height: 150,
              child: const ElectricAnimated(
                duration: 3,
                path: [
                  Offset(30, 0),
                  Offset(30, 67),
                  Offset(90, 67),
                  Offset(90, 137),
                ],
              ),
            ),
          ),
    

    CSDN地址

    相关文章

      网友评论

          本文标题:Flutter类似于电力输送的动画

          本文链接:https://www.haomeiwen.com/subject/dlmsgdtx.html