FluxWater/lib/widgets/cozy_wave.dart

88 lines
2.1 KiB
Dart

import 'dart:math' as math;
import 'package:flutter/material.dart';
class CozyWave extends StatefulWidget {
final double percentage;
final Color color;
const CozyWave({super.key, required this.percentage, required this.color});
@override
State<CozyWave> createState() => _CozyWaveState();
}
class _CozyWaveState extends State<CozyWave>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 3),
)..repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return ClipPath(
clipper: WaveClipper(_controller.value, widget.percentage),
child: Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [widget.color, widget.color.withOpacity(0.8)],
),
),
),
);
},
);
}
}
class WaveClipper extends CustomClipper<Path> {
final double animationValue;
final double percentage;
WaveClipper(this.animationValue, this.percentage);
@override
Path getClip(Size size) {
final path = Path();
final double baseHeight = size.height * (1 - percentage);
path.moveTo(0, baseHeight);
for (double i = 0; i <= size.width; i++) {
path.lineTo(
i,
baseHeight +
math.sin(
(i / size.width * 2 * math.pi) +
(animationValue * 2 * math.pi),
) *
8,
);
}
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
path.close();
return path;
}
@override
bool shouldReclip(WaveClipper oldClipper) => true;
}