workouttest_app/lib/library/liquid_progress_indicator/wave.dart
2021-04-19 00:16:07 +02:00

115 lines
2.8 KiB
Dart

import 'dart:math' as math;
import 'package:flutter/material.dart';
class Wave extends StatefulWidget {
final double value;
final Color color;
final Axis direction;
const Wave({
Key? key,
required this.value,
required this.color,
required this.direction,
}) : super(key: key);
@override
_WaveState createState() => _WaveState();
}
class _WaveState extends State<Wave> with SingleTickerProviderStateMixin {
late AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
);
_animationController.repeat();
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
),
builder: (context, child) => ClipPath(
child: Container(
color: widget.color,
),
clipper: _WaveClipper(
animationValue: _animationController.value,
value: widget.value,
direction: widget.direction,
),
),
);
}
}
class _WaveClipper extends CustomClipper<Path> {
final double animationValue;
final double value;
final Axis direction;
_WaveClipper({
required this.animationValue,
required this.value,
required this.direction,
});
@override
Path getClip(Size size) {
if (direction == Axis.horizontal) {
Path path = Path()
..addPolygon(_generateHorizontalWavePath(size), false)
..lineTo(0.0, size.height)
..lineTo(0.0, 0.0)
..close();
return path;
}
Path path = Path()
..addPolygon(_generateVerticalWavePath(size), false)
..lineTo(size.width, size.height)
..lineTo(0.0, size.height)
..close();
return path;
}
List<Offset> _generateHorizontalWavePath(Size size) {
final waveList = <Offset>[];
for (int i = -2; i <= size.height.toInt() + 2; i++) {
final waveHeight = (size.width / 20);
final dx = math.sin((animationValue * 360 - i) % 360 * (math.pi / 180)) * waveHeight + (size.width * value);
waveList.add(Offset(dx, i.toDouble()));
}
return waveList;
}
List<Offset> _generateVerticalWavePath(Size size) {
final waveList = <Offset>[];
for (int i = -2; i <= size.width.toInt() + 2; i++) {
final waveHeight = (size.height / 20);
final dy = math.sin((animationValue * 360 - i) % 360 * (math.pi / 180)) * waveHeight + (size.height - (size.height * value));
waveList.add(Offset(i.toDouble(), dy));
}
return waveList;
}
@override
bool shouldReclip(_WaveClipper oldClipper) => animationValue != oldClipper.animationValue;
}