compass2.dart 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. import 'dart:math';
  2. import 'package:flutter/material.dart';
  3. import 'package:get/get.dart';
  4. import '../styles/theme.dart';
  5. const _textHeight = 45.0;
  6. class Compass2 extends StatelessWidget {
  7. static const levelMin = 1;
  8. static const levelMax = 5;
  9. const Compass2(
  10. {super.key,
  11. this.compassRadians,
  12. required this.mapNorthRadians,
  13. this.nextPointRadians,
  14. required this.level,
  15. required this.showDegrees,
  16. required this.diameter,
  17. this.nextPointImage,
  18. this.nextPointHeight,
  19. this.degreeColor,
  20. this.plantSrc,
  21. });
  22. final double diameter;
  23. final int level;
  24. /// 指南针方向
  25. final double? compassRadians;
  26. /// 地图北的方向
  27. final double mapNorthRadians;
  28. /// 下一点方向
  29. final double? nextPointRadians;
  30. /// 显示度数
  31. final int showDegrees;
  32. final Widget? nextPointImage;
  33. final double? nextPointHeight;
  34. final Color? degreeColor;
  35. final String? plantSrc;
  36. @override
  37. Widget build(BuildContext context) {
  38. return SizedBox(
  39. width: diameter,
  40. height: diameter,
  41. child: Stack(
  42. alignment: Alignment.center,
  43. children: [
  44. Container(
  45. decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.white.withAlpha(125)),
  46. width: diameter- _textHeight,
  47. height: diameter- _textHeight,
  48. ),
  49. Transform.rotate(angle: mapNorthRadians, child: SizedBox(
  50. width: diameter - _textHeight,
  51. height: diameter - _textHeight,
  52. child:_Compass(level: level, src: plantSrc),
  53. ),),
  54. nextPointRadians != null? Transform.rotate(angle: nextPointRadians!, child: SizedBox(
  55. width: diameter - _textHeight - diameter * 0.3,
  56. height: nextPointHeight?? diameter - _textHeight - diameter * 0.3,
  57. child: nextPointImage??
  58. Image.asset('assets/images/im_compass_next_arrow.png',
  59. fit: BoxFit.fitHeight),
  60. )): const SizedBox(),
  61. compassRadians != null?
  62. Transform.rotate(angle: compassRadians!, child: SizedBox(
  63. width: diameter - _textHeight,
  64. height: diameter - _textHeight,
  65. child: Image.asset('assets/images/im_compass_arrow.png', height: context.height, width: context.width, fit: BoxFit.fill),
  66. ),): const SizedBox(),
  67. level < levelMax ?
  68. SizedBox(
  69. width: diameter,
  70. height: diameter,
  71. child: _MapNorthArrow(showDegrees, degreeColor),
  72. ): const SizedBox(),
  73. ],
  74. )
  75. ) ;
  76. }
  77. }
  78. class _MapNorthArrow extends StatelessWidget{
  79. const _MapNorthArrow(this.degrees, this.degreeColor);
  80. final int degrees;
  81. final Color? degreeColor;
  82. @override
  83. Widget build(BuildContext context) {
  84. return Column(
  85. children: [
  86. SizedBox(
  87. height: _textHeight,
  88. child: Column(
  89. children:[
  90. Text(' $degrees°', style: TextStyle(fontSize: 12, color: degreeColor??Colors.black)),
  91. CustomPaint(painter: _MapNorthArrowPainter(), size: const Size(10, 10),) ,
  92. ]
  93. ),
  94. ),
  95. const Spacer(),
  96. ],
  97. );
  98. }
  99. }
  100. class _MapNorthArrowPainter extends CustomPainter {
  101. final painter = Paint()
  102. ..color = Colors.black;
  103. final path = Path();
  104. @override
  105. void paint(Canvas canvas, Size size) {
  106. final centerX = size.width/2;
  107. path.moveTo(centerX-2, 0);
  108. path.lineTo(centerX+2, 0);
  109. path.lineTo(centerX, size.height);
  110. path.close();
  111. canvas.drawPath(path, painter);
  112. }
  113. @override
  114. bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
  115. }
  116. class _Compass extends StatelessWidget{
  117. const _Compass({required this.level, required this.src});
  118. final int level;
  119. final String? src;
  120. @override
  121. Widget build(BuildContext context) {
  122. String? plantSrc;
  123. switch(level){
  124. case 1:
  125. plantSrc = 'assets/images/im_compass_1.png';
  126. break;
  127. case 2:
  128. plantSrc = 'assets/images/im_compass_2.png';
  129. break;
  130. case 3:
  131. plantSrc = 'assets/images/im_compass_3.png';
  132. break;
  133. case 4:
  134. plantSrc = 'assets/images/im_compass_4.png';
  135. break;
  136. default:
  137. break;
  138. }
  139. if(src != null){
  140. plantSrc = src;
  141. }
  142. final children = <Widget>[];
  143. if(plantSrc!= null){
  144. children.add(
  145. Image.asset(plantSrc, height: context.height, width: context.width, fit: BoxFit.fill)
  146. );
  147. }
  148. return Stack(
  149. children: children,
  150. );
  151. }
  152. }
  153. void main() async {
  154. runApp(GetMaterialApp(
  155. theme: appThemeData(),
  156. home: Container(
  157. width: double.infinity,
  158. height: double.infinity,
  159. color: Colors.white,
  160. alignment: Alignment.center,
  161. child: Compass2(
  162. compassRadians: pi/2,
  163. mapNorthRadians: 0,
  164. level: 1,
  165. nextPointRadians: -pi/2,
  166. showDegrees: 100,
  167. diameter: 160,
  168. ))));
  169. }