162 lines
4.3 KiB
Dart
162 lines
4.3 KiB
Dart
import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'dart:math';
|
|
import 'package:google_fonts/google_fonts.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(0xFF0D74E2),
|
|
const Color(0xFF0DB8E2),
|
|
const Color(0xFF0DD8E2),
|
|
const Color(0xFF0DE2BB),
|
|
const Color(0xFF0DE2A1),
|
|
const Color(0xFF0DE284),
|
|
const Color(0xFF0DE25E),
|
|
const Color(0xFF0DE244),
|
|
const Color(0xFF84E20D),
|
|
const Color(0xFFC2E20D),
|
|
const Color(0xFFE2DF0D),
|
|
const Color(0xFFE2A10D),
|
|
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({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;
|
|
|
|
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;
|
|
}
|
|
}
|