| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- import 'package:trackoffical_app/screen.dart';
- import 'package:trackoffical_app/utils.dart';
- import 'package:vector_math/vector_math_64.dart' as vec;
- import '../../../widget/compass2.dart';
- import '../game_std/utils.dart';
- import '../widget_ruler2.dart';
- import 'game_compass_top4_data.dart';
- export 'game_compass_top4_data.dart';
- export 'game_compass_button.dart';
- export 'package:flutter/material.dart';
- class GameCompassController{
- final heartRatePercent = 0.0.obs;
- final isNoMapRulerScaleMode=false.obs;
- final duration = 0.seconds.obs;
- final compassRadians= 0.0.obs;
- final nextPointRadians= 0.0.obs;
- final heartRate = 0.obs;
- final stepCount=0.obs;
- final kCal= 0.0.obs;
- final ck= 0.0.obs;
- final ei= 0.0.obs;
- /// 地图比例尺 1:[userSetMapScale]
- final Rx<double?> userSetMapScale = Rx(null);
- }
- class GameCompassBase extends StatelessWidget{
- const GameCompassBase({
- super.key,
- required this.controller,
- required this.top4data,
- required this.topButtons,
- required this.process,
- this.compassDiameter=230,
- required this.isShowNextPointer,
- required this.isEnableRuler, required this.bottomCenterButton,
- });
- static const _hPadding = 60.0;
- final GameCompassController controller;
- final List<GameCompassTop4Data> top4data;
- final List<Widget> topButtons;
- final Widget? process;
- final double compassDiameter;
- final bool isShowNextPointer;
- final bool isEnableRuler;
- final Widget bottomCenterButton;
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- body: DefaultTextStyle(
- style: const TextStyle(color: Colors.white),
- child: Stack(
- children: [
- Obx(() => Container(
- decoration: BoxDecoration(
- color: controller.heartRatePercent.value.round().toHRPColor()),
- width: context.width,
- height: context.height,
- )),
- Obx(() => !controller.isNoMapRulerScaleMode.value
- ? const Ruler2(isScaleMode: false)
- : const SizedBox()),
- Container(
- padding: EdgeInsets.only(
- top: context.mediaQueryPadding.top,
- left: _hPadding,
- right: _hPadding),
- width: context.width,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- const SizedBox(height: 20),
- _topButtonBar(),
- _wDuration(),
- _process(),
- _topElemHub(),
- _compass(),
- _heartRate(),
- _sports(),
- _bottomBar(),
- ])),
- Obx(() => controller.isNoMapRulerScaleMode.value && isEnableRuler
- ? Ruler2(
- isScaleMode: true,
- onReturn: () =>
- controller.isNoMapRulerScaleMode.value = false,
- mapScale: controller.userSetMapScale.value)
- : const SizedBox(height: 0))
- ],
- ),
- ));
- }
- Widget _topButtonBar() {
- return Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: topButtons,
- );
- }
- Widget _wDuration() {
- return Obx(() => Text(controller.duration.value.toAppString(),
- maxLines: 1,
- style: const TextStyle(
- fontSize: 29,
- fontFamily: 'sa-digital-number',
- )));
- }
- Widget _process() {
- final w = process;
- return w!= null?DefaultTextStyle(style: const TextStyle(
- fontSize: 32,
- ), child: w): const SizedBox();
- }
- Widget _topElemHub() {
- final rows = <Widget>[];
- final titles = <Widget>[];
- final divider = SizedBox(width: 2.78.wp);
- rows.add(Row(
- children: [
- top4data[0],
- divider,
- top4data[1],
- ],
- ));
- titles.addAll([
- Positioned(
- left: 0,
- top: 0,
- child: _getSmallTitle(top4data[0].title)
- ),
- Positioned(
- right: 0,
- top: 0,
- child: _getSmallTitle(top4data[1].title)
- ),
- ]);
- if(top4data.length==4){
- rows.add(SizedBox(height: 2.78.wp));
- rows.add(Row(
- children: [
- top4data[2],
- divider,
- top4data[3],
- ],
- ));
- titles.addAll([
- Positioned(
- left: 0,
- bottom: 0,
- child: _getSmallTitle(top4data[2].title)
- ),
- Positioned(
- right: 0,
- bottom: 0,
- child: _getSmallTitle(top4data[3].title)
- ),
- ]);
- }
- final stacks = <Widget>[
- Column(
- children: rows,
- )
- ];
- stacks.addAll(titles);
- return Stack(
- children: stacks,
- ) ;
- }
- Widget _getSmallTitle(String title){
- return Container(
- alignment: Alignment.center,
- padding: const EdgeInsets.only(left: 3, right: 3),
- decoration: const BoxDecoration(color: Colors.black),
- child: Text(title,
- style: const TextStyle(
- fontSize:11,
- color: Colors.white,
- fontWeight: FontWeight.w700))
- );
- }
- Widget _compass() {
- return Obx(() {
- final radians = controller.compassRadians.value;
- return Compass2(
- compassRadians: radians,
- mapNorthRadians: radians,
- nextPointRadians: isShowNextPointer? controller.nextPointRadians.value: null,
- level: 1,
- showDegrees: vec.degrees(radians).compassDegrees,
- diameter: compassDiameter,
- nextPointImage: Image.asset('assets/images/im_compass_next_arrow2.png'),
- nextPointHeight: 100,
- degreeColor: Colors.white,
- plantSrc: 'assets/images/im_compass_no_map.png',
- );
- } );
- }
- Widget _heartRate() {
- return Obx(() => Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- wHrp(),
- Container(
- width: 1,
- height: 53,
- color: Colors.white.withAlpha((255 * 0.3).round())),
- wHr(),
- ],
- ));
- }
- Widget wHrp() {
- final hrp = controller.heartRatePercent.value.round();
- return Row(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text('$hrp',
- style: const TextStyle(fontSize: 43, fontWeight: FontWeight.w700)),
- const Text('%',
- style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700))
- ],
- );
- }
- Widget wHr() {
- return Row(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text('${controller.heartRate.value}',
- style: const TextStyle(fontSize: 43, fontWeight: FontWeight.w700)),
- Padding(
- padding: const EdgeInsets.only(top: 5),
- child: Image.asset('assets/images/ic_heart.png', height: 14.4))
- ],
- );
- }
- Widget _sports() {
- const style = TextStyle(fontSize: 15.24, fontWeight: FontWeight.w500);
- return Obx(() => Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- wSport(
- '${controller.stepCount.value}', 'assets/images/ic_step_count.png',
- textStyle: style),
- wSport(controller.kCal.value.toStringAsFixed(1),
- 'assets/images/ic_kcal.png',
- textStyle: style),
- wSport(
- controller.ck.value.toStringAsFixed(1), 'assets/images/ic_ck.png',
- textStyle: style),
- wSport(controller.ei.round().toString(), 'assets/images/ic_ei.png',
- textStyle: style),
- ],
- ));
- }
- Widget _bottomBar() {
- return Padding(
- padding: const EdgeInsets.only(bottom: 20, left: 20, right: 20),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- isEnableRuler?
- GestureDetector(
- onTap: _onSetMapScale,
- child: Image.asset('assets/images/btn_ruler_scale_no_map.png',
- width: 46,
- )): const SizedBox(),
- bottomCenterButton,
- isEnableRuler?
- GestureDetector(
- onTap: () => controller.isNoMapRulerScaleMode.value = true,
- child: Image.asset(
- 'assets/images/btn_ruler_no_map.png',
- width: 46,
- )): const SizedBox()
- ],
- ));
- }
- _onSetMapScale() {
- var value = controller.userSetMapScale.value?.toString() ?? '';
- Get.dialog(AlertDialog(
- title: const Text('设置比例尺'),
- content: Row(
- children: [
- const Text(
- '1 :',
- style: TextStyle(fontSize: 16),
- ),
- const SizedBox(
- width: 6,
- ),
- SizedBox(
- width: 120,
- child: TextField(
- onChanged: (v) {
- value = v;
- },
- keyboardType: TextInputType.number,
- controller: TextEditingController.fromValue(
- TextEditingValue(text: value)))),
- ],
- ),
- actions: [
- TextButton(
- onPressed: () {
- Get.back();
- },
- child: const Text('取消')),
- TextButton(
- onPressed: () {
- controller.userSetMapScale.value = double.tryParse(value)!;
- Get.back();
- },
- child: const Text('确定')),
- ],
- ));
- }
- }
|