Flutter类似于电力输送的动画

利用flutter写了个类似于充电的动画,比如光伏板给电池充电,模仿电力输送的过程,效果如下图所示
下面直接贴出代码,属性都标注了注释,使用的时候在外面加个盒子固定宽高,然后给出每个点的坐标,内部会根据坐标的点数来判断有几根线,然后画出线的路径,进行动画模拟,可以根据项目需求来自定义点的颜色,每条路径上点的个数以及点的大小等等,
复制代码
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),
            ],
          ),
        ),
      ),

简书地址

相关推荐
xiangzhihong85 分钟前
使用Universal Links与Android App Links实现网页无缝跳转至应用
android·ios
车载应用猿1 小时前
基于Android14的CarService 启动流程分析
android
没有了遇见1 小时前
Android 渐变色实现总结
android
UrbanJazzerati2 小时前
使用 Thunder Client 调用 Salesforce API 的完整指南
面试·visual studio code
Digitally2 小时前
如何将iPhone备份到Mac/MacBook
macos·ios·iphone
帅次3 小时前
【iOS设计模式】深入理解MVC架构 - 重构你的第一个App
ios·swiftui·objective-c·iphone·swift·safari·cocoapods
雨白4 小时前
Jetpack系列(四):精通WorkManager,让后台任务不再失控
android·android jetpack
mmoyula6 小时前
【RK3568 驱动开发:实现一个最基础的网络设备】
android·linux·驱动开发
sam.li7 小时前
WebView安全实现(一)
android·安全·webview
你听得到117 小时前
从需求到封装:手把手带你打造一个高复用、可定制的Flutter日期选择器
前端·flutter