workouttest_app/lib/library/clock.dart
2021-04-02 11:42:26 +02:00

164 lines
4.4 KiB
Dart

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';
final temperatureColors = [
const Color(0xFFB50DE2), // -20 Celsius , friggin cold
const Color(0xFFAE0DE2),
const Color(0xFF980DE2),
const Color(0xFF8E0DE2),
const Color(0xFF810DE2),
const Color(0xFF7B0DE2),
const Color(0xFF670DE2),
const Color(0xFF570DE2),
const Color(0xFF4A0DE2),
const Color(0xFF410DE2),
const Color(0xFF1D0DE2),
const Color(0xFF0D4AE2),
const Color(0xFF0D57E2),
const Color(0xFF012e7d),
const Color(0xFF01417d),
const Color(0xFF01737d),
const Color(0xFF017d71),
const Color(0xFF017d49),
const Color(0xFF017d1c),
const Color(0xFF317d01),
const Color(0xFF477d01),
const Color(0xFF607d01),
const Color(0xFF7d7d01),
const Color(0xFF7d6001),
const Color(0xFF7d4701),
const Color(0xFFE2740D),
const Color(0xFFE2510D),
const Color(0xFFE22D0D),
const Color(0xFFE2100D),
const Color(0xFFE20D17), // 40 Celsius, rather be dead
];
// ignore: must_be_immutable
class Clock extends StatelessWidget {
final TimerBloc bloc;
final List<Color> colors = temperatureColors;
Clock({required this.bloc});
// ignore: close_sinks
final Paint paintSeconds = Paint()
..strokeCap = StrokeCap.butt
..style = PaintingStyle.stroke
..strokeWidth = 4
..isAntiAlias = true;
final Paint paintMinutes = Paint()
..strokeCap = StrokeCap.butt
..style = PaintingStyle.stroke
..strokeWidth = 4
..isAntiAlias = true;
final Paint paintHours = Paint()
..strokeCap = StrokeCap.butt
..style = PaintingStyle.stroke
..strokeWidth = 4
..isAntiAlias = true;
@override
Widget build(BuildContext context) {
return BlocBuilder<TimerBloc, TimerState>(builder: (context, state) {
if (state is TimerRunning) {
return getLayout(bloc.state);
} else {
return Offstage();
}
});
}
Widget getLayout(TimerState state) {
int duration = 300 - state.duration;
int seconds = (duration % 60).floor();
int minutes = ((duration / 60) % 60).floor();
String secondStr = seconds.toString().padLeft(2, '0');
String time = minutes == 0 ? "$secondStr" : "$minutes:$secondStr";
return LayoutBuilder(builder: (context, constraints) {
return Stack(
alignment: Alignment.center,
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: 37,
left: (45 - time.length / 2 * 9).toDouble(), //seconds < 10 ? 37 : 30,
child: Text(
"$time",
style: GoogleFonts.kosugi(color: colors[(seconds ~/ 2)], fontSize: 16),
)),
CustomPaint(painter: ArcPainter(minutes, paintMinutes, 5, constraints.maxHeight * 0.40, 0.15, colors)),
CustomPaint(painter: ArcPainter(seconds, paintSeconds, 60, constraints.maxHeight * 0.34, 0.2, colors)),
],
);
});
}
}
class ArcPainter extends CustomPainter {
int _progress;
Paint _paint;
int _units;
double _gap;
List<Color> _gradient;
Offset? center;
double _radius;
late Paint paintMarkerEmpty;
ArcPainter(
this._progress,
this._paint,
this._units,
this._radius,
this._gap,
this._gradient,
) {
this.paintMarkerEmpty = Paint()
..strokeCap = StrokeCap.butt
..style = PaintingStyle.stroke
..strokeWidth = this._paint.strokeWidth
..isAntiAlias = true;
}
@override
void paint(Canvas canvas, Size size) {
center = Offset(size.width / 2, size.height / 2);
var rect = Rect.fromCircle(center: center!, radius: this._radius);
final gradient2 = new SweepGradient(
startAngle: -pi / 2,
endAngle: (-pi / 2) + (pi * 2),
tileMode: TileMode.repeated,
colors: this._gradient,
);
this._paint.shader = gradient2.createShader(rect);
this.paintMarkerEmpty.color = this._gradient[0].withOpacity(0.2);
for (var i = 0; i < this._units; i++) {
final double unit = 2 * pi / this._units;
double start = unit * i;
double to = (((2 * pi) / this._units) + unit);
canvas.drawArc(rect, (-pi / 2 + start), to * 2 * this._gap, false, i < this._progress ? this._paint : this.paintMarkerEmpty);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}