113 lines
2.7 KiB
Dart
113 lines
2.7 KiB
Dart
import 'dart:ui';
|
|
import 'package:flutter/material.dart';
|
|
|
|
/// 球体配置类:控制颜色、大小、以及运动轨迹
|
|
class GlowBlobConfig {
|
|
final Color color;
|
|
final double size;
|
|
final Alignment begin;
|
|
final Alignment end;
|
|
|
|
GlowBlobConfig({
|
|
required this.color,
|
|
required this.size,
|
|
required this.begin,
|
|
required this.end,
|
|
});
|
|
}
|
|
|
|
class LiquidGlowBackground extends StatefulWidget {
|
|
// 支持传入配置列表
|
|
final List<GlowBlobConfig> blobs;
|
|
final Duration duration;
|
|
final double blurSigma;
|
|
|
|
const LiquidGlowBackground({
|
|
super.key,
|
|
required this.blobs,
|
|
this.duration = const Duration(seconds: 8),
|
|
this.blurSigma = 50.0,
|
|
});
|
|
|
|
@override
|
|
State<LiquidGlowBackground> createState() => _LiquidGlowBackgroundState();
|
|
}
|
|
|
|
class _LiquidGlowBackgroundState extends State<LiquidGlowBackground>
|
|
with SingleTickerProviderStateMixin {
|
|
late AnimationController _controller;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_controller = AnimationController(
|
|
vsync: this,
|
|
duration: widget.duration,
|
|
)..repeat(reverse: true); // 设置为 reverse 让往返运动更丝滑
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_controller.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AnimatedBuilder(
|
|
animation: _controller,
|
|
builder: (context, child) {
|
|
return Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
// 根据传入的配置动态生成球体
|
|
...widget.blobs.map((config) {
|
|
// 使用 AnimationController 在 begin 和 end 之间插值
|
|
final currentAlignment = Alignment.lerp(
|
|
config.begin,
|
|
config.end,
|
|
_controller.value,
|
|
)!;
|
|
|
|
return _buildBlob(
|
|
color: config.color,
|
|
size: config.size,
|
|
alignment: currentAlignment,
|
|
);
|
|
}),
|
|
|
|
// 核心模糊效果层
|
|
Positioned.fill(
|
|
child: BackdropFilter(
|
|
filter: ImageFilter.blur(
|
|
sigmaX: widget.blurSigma,
|
|
sigmaY: widget.blurSigma,
|
|
),
|
|
child: Container(color: Colors.transparent),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
Widget _buildBlob({
|
|
required Color color,
|
|
required double size,
|
|
required Alignment alignment,
|
|
}) {
|
|
return Align(
|
|
alignment: alignment,
|
|
child: Container(
|
|
width: size,
|
|
height: size,
|
|
decoration: BoxDecoration(
|
|
color: color,
|
|
shape: BoxShape.circle,
|
|
backgroundBlendMode: BlendMode.screen, // 让光影融合更自然
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |