clock_page.dart 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import 'dart:async';
  2. import 'dart:math' as math;
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_clock/model/config.dart';
  5. import 'package:intl/intl.dart';
  6. class ClockPage extends StatefulWidget {
  7. @override
  8. State<StatefulWidget> createState() {
  9. return _ClockPageState();
  10. }
  11. }
  12. class _ClockPageState extends State<ClockPage> {
  13. final _utcMidnightRadiansOffset = radiansFromDegrees(-64);
  14. static const _secondsInDay = 86400;
  15. DateTime _localTime = DateTime.now();
  16. @override
  17. void initState() {
  18. super.initState();
  19. Timer.periodic(Duration(seconds: 1),
  20. (_) => setState(() => _localTime = DateTime.now()));
  21. }
  22. @override
  23. Widget build(BuildContext context) {
  24. return Scaffold(
  25. backgroundColor: Colors.white,
  26. body: SingleChildScrollView(
  27. child: Center(
  28. child: Column(
  29. children: [
  30. SizedBox(height: 20),
  31. Stack(
  32. children: [
  33. Image.asset(
  34. 'assets/face.png',
  35. width: 350,
  36. ),
  37. Transform.rotate(
  38. angle: -(radiansFromTime(_localTime.toUtc()) +
  39. _utcMidnightRadiansOffset),
  40. child: ClipOval(
  41. clipper: InnerFaceClipper(),
  42. child: Image.asset(
  43. 'assets/face.png',
  44. width: 350,
  45. ),
  46. ),
  47. ),
  48. ],
  49. ),
  50. SizedBox(height: 20),
  51. Text(DateFormat.EEEE().format(_localTime),
  52. style: TextStyle(fontSize: 48)),
  53. Text(DateFormat.yMMMMd().format(_localTime),
  54. style: TextStyle(fontSize: 20)),
  55. Text(DateFormat.jms().format(_localTime),
  56. style: TextStyle(fontSize: 42)),
  57. ],
  58. ),
  59. ),
  60. ));
  61. }
  62. static double radiansFromDegrees(double degrees) => degrees * math.pi / 180;
  63. static double radiansFromTime(DateTime time) {
  64. final midnightToday = DateTime(time.year, time.month, time.day);
  65. final secondsSinceMidnight = midnightToday.difference(time).inSeconds;
  66. final percent = secondsSinceMidnight / _secondsInDay;
  67. final degrees = percent * 360;
  68. return radiansFromDegrees(degrees);
  69. }
  70. }
  71. class InnerFaceClipper extends CustomClipper<Rect> {
  72. final percent = 0.85;
  73. @override
  74. Rect getClip(Size size) => Rect.fromCenter(
  75. center: size.center(Offset(0, 0)),
  76. width: size.width * percent,
  77. height: size.height * percent,
  78. );
  79. @override
  80. bool shouldReclip(CustomClipper oldClipper) => true;
  81. }