clock_page.dart 2.7 KB

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