如何用Flutter实现电子动画?使用AnimatedPositioned遇多容器动画难题
Flutter 实现电路电子流动动画方案
AnimatedPositioned更适合单次位置切换的场景,要实现类似目标GIF里的连续电子流动效果,需要用循环动画控制器配合多组件延迟启动,以下是具体实现方案:
核心思路
- 用
Stack层叠SVG电路背景和电子容器 - 为每个电子单独创建
AnimationController,通过Tween定义流动路径的起始/结束位置 - 给不同电子设置启动延迟,模拟连续流动的视觉效果
- 若需要折线/曲线路径,可通过
TweenSequence或路径计算实现多段动画
代码实现
1. 先添加依赖(加载SVG)
在pubspec.yaml中添加:
dependencies: flutter: sdk: flutter flutter_svg: ^2.0.9
2. 封装电子组件
import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; class Electron extends StatefulWidget { final double startX; final double startY; final double endX; final double endY; final Duration duration; final int delayMs; const Electron({ super.key, required this.startX, required this.startY, required this.endX, required this.endY, required this.duration, required this.delayMs, }); @override State<Electron> createState() => _ElectronState(); } class _ElectronState extends State<Electron> with SingleTickerProviderStateMixin { late AnimationController _animController; late Animation<double> _xAnim; late Animation<double> _yAnim; @override void initState() { super.initState(); _animController = AnimationController( vsync: this, duration: widget.duration, ); // 定义X/Y轴的线性流动动画 _xAnim = Tween<double>(begin: widget.startX, end: widget.endX).animate( CurvedAnimation(parent: _animController, curve: Curves.linear), ); _yAnim = Tween<double>(begin: widget.startY, end: widget.endY).animate( CurvedAnimation(parent: _animController, curve: Curves.linear), ); // 延迟启动后循环播放 Future.delayed(Duration(milliseconds: widget.delayMs), () { _animController.repeat(reverse: false); }); } @override void dispose() { _animController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _animController, builder: (ctx, child) { return Positioned( left: _xAnim.value, top: _yAnim.value, child: const CircleAvatar( radius: 4, backgroundColor: Colors.blueAccent, ), ); }, ); } }
3. 组合动画页面
class CircuitFlowAnimation extends StatelessWidget { const CircuitFlowAnimation({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ // 加载你的电路SVG背景 SvgPicture.asset( 'assets/circuit_diagram.svg', width: double.infinity, height: double.infinity, fit: BoxFit.contain, ), // 横向流动的电子组 Electron( startX: 60, startY: 120, endX: 320, endY: 120, duration: const Duration(seconds: 2), delayMs: 0, ), Electron( startX: 60, startY: 120, endX: 320, endY: 120, duration: const Duration(seconds: 2), delayMs: 300, ), Electron( startX: 60, startY: 120, endX: 320, endY: 120, duration: const Duration(seconds: 2), delayMs: 600, ), // 纵向流动的电子组(模拟电路转弯) Electron( startX: 320, startY: 120, endX: 320, endY: 280, duration: const Duration(seconds: 1.5), delayMs: 200, ), Electron( startX: 320, startY: 120, endX: 320, endY: 280, duration: const Duration(seconds: 1.5), delayMs: 500, ), ], ), ); } }
进阶优化
- 曲线路径支持:如果需要沿复杂电路路径流动,可以通过
Path和PathMetric计算路径上的坐标点,用AnimationController驱动获取实时位置,替代简单的X/Y Tween - 性能优化:当电子数量超过10个时,建议用
CustomPainter批量绘制所有电子,减少Widget树的节点数量,提升流畅度 - 动画曲线调整:替换
Curves.linear为其他曲线(如Curves.easeInOut),可以模拟电子加速/减速的效果
内容的提问来源于stack exchange,提问作者Ahm2025
相关产品推荐
相关产品推荐

