import 'dart:async'; import 'dart:math'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:get/get.dart'; import 'package:scence_map/controllers/controller.dart'; import '../../controllers/gnss_Controller.dart'; import '../../service/pile/device_type.dart'; import 'aimpointController.dart'; final AimPointerController aimcontroller = Get.put(AimPointerController()); final ScenceMapController mapcontroller = Get.put(ScenceMapController()); final GnssController gnsscontroller = Get.put(GnssController()); class AimPointer extends GetView { String gradienter = "0"; //水平仪 @override Widget build(BuildContext context) { final Size size = MediaQuery.of(context).size; MediaQueryData mediaQueryData = MediaQueryData.fromView(WidgetsBinding.instance.window); //获取当前屏幕信息 final orientation = mediaQueryData.orientation; //获得设备方向 bool isPortrait = Orientation.portrait == orientation ? true : false; double rectWidth = size.width; final deviceType = getDeviceType(context); if (orientation == Orientation.landscape) { rectWidth = size.width / 2 - 60; if (deviceType == DeviceType.mobile) { rectWidth = size.height - 130; } } else { rectWidth = size.height / 2; if (deviceType == DeviceType.mobile) { rectWidth = size.width - 5; } } bool isDarkMode = Theme.of(context).brightness == Brightness.dark; List children = [ SizedBox( width: rectWidth, height: rectWidth, child: Card( clipBehavior: Clip.antiAlias, shape: RoundedRectangleBorder( side: BorderSide(color: Colors.transparent, width: 0), borderRadius: BorderRadius.circular(4.0), // 可以根据需要调整圆角半径 ), child: Stack( children: [ Container( width: rectWidth, height: rectWidth, decoration: BoxDecoration( border: Border.all( color: isDarkMode ? Colors.white : Colors.black), borderRadius: BorderRadius.all(Radius.circular(rectWidth / 2)), ), child: Stack( children: [ CustomPaint( //绘制瞄准器 size: Size(rectWidth, rectWidth), painter: DrawAxis(aimcontroller, 0, 0, isDarkMode), child: Stack( children: [ Positioned( top: 20, left: 20, child: Obx(() { return TextButton( child: Text( "${aimcontroller.plot.value}m", style: const TextStyle(fontSize: 20), ), onPressed: () { if (aimcontroller.plot.value == 1) { aimcontroller.plot.value = 2; } else { aimcontroller.plot.value = 1; } aimcontroller.update(); }, ); })), Positioned( top: 25, right: 10, child: TextButton( child: Text( "垂直度:$gradienter°", style: const TextStyle(fontSize: 20), ), onPressed: () {}, )), Positioned( right: 0, top: 0, child: IconButton( icon: const Icon(Icons.close), onPressed: () { // 关闭按钮的回调函数 aimcontroller.isCardVisible.value = false; aimcontroller.lastCloseTapTime = DateTime.now().millisecondsSinceEpoch; }, ), ), Obx(() { var pixel2MeterRatio = aimcontroller.plot.value * 2 / rectWidth; if (aimcontroller.selectedPilePoint != null) gnsscontroller.device.update.value; if (aimcontroller.selectedPilePoint != null) { var dx = (gnsscontroller.device.x - aimcontroller.selectedPilePoint!.x); var dy = (gnsscontroller.device.y - aimcontroller.selectedPilePoint!.y); aimcontroller.top.value = dx * cos(mapcontroller.rotation.value) + dy * sin(mapcontroller.rotation.value); aimcontroller.left.value = -dx * sin(mapcontroller.rotation.value) + dy * cos(mapcontroller.rotation.value); // aimcontroller.positionUpdate.value++; print("dx:$dx,dy:$dy"); print( "left:${aimcontroller.left.value},top:${aimcontroller.top.value}"); } return Positioned( left: rectWidth / 2 - 30 + aimcontroller.left.value / pixel2MeterRatio, top: rectWidth / 2 - 30 - aimcontroller.top.value / pixel2MeterRatio, // left: 70, // top: 70, child: Transform( transform: Matrix4.identity() ..rotateZ( gnsscontroller.device.rotation + pi / 2 + mapcontroller.rotation.value), alignment: FractionalOffset.center, child: Stack( alignment: Alignment.center, children: [ SizedBox( width: 60.0, // 设置图像的宽度 height: 60.0, // 设置图像的高度 child: Image.asset( "images/navi_pointer.png", errorBuilder: (context, error, stackTrace) { return Text('无法加载图片'); }, ), ), // Obx(() { // Offset offset = controller.xy2Screen( // gnsscontroller.pilerCenter.X, gnsscontroller.pilerCenter.Y); // return Positioned( // left: offset.dx, // top: offset.dy, // child: Transform( // transform: Matrix4.identity() // ..rotateZ(-controller.rotation.value), // child: Column( // children: [Text("设备:${item.name}")], // ), // ), // ); // }), ], ))); }) ], )) ], )), ], ), ), ), const SizedBox( width: 5, height: 5, ), const Expanded( child: Text(""), ), ]; if (isPortrait) { return Column( children: children, ); } else { return Row( children: children, ); } } } class DrawAxis extends CustomPainter { final AimPointerController aimcontroller; final double tiltX; final double tiltY; final bool isDarkMode; DrawAxis(this.aimcontroller, this.tiltX, this.tiltY, this.isDarkMode); final _paint = Paint(); //创建一个画笔并配置其属性 Path path = Path(); List icons = [ Icons.arrow_drop_up, Icons.arrow_drop_down, Icons.arrow_left, Icons.arrow_right ]; List iconOffset = []; List text = ["", "", "", ""]; //['前移', '后移', '左移', '右移']; @override void paint(Canvas canvas, size) { _paint ..strokeWidth = 2 ..style = PaintingStyle.stroke ..color = const Color.fromARGB(255, 183, 183, 162); double rectWidth = (size.height / 2 - 5).roundToDouble(); aimcontroller.cardWidth.value = rectWidth; if (!aimcontroller.isNomal.value) { } else {} path.moveTo(0, rectWidth + 5); path.lineTo(size.height, rectWidth + 5); path.moveTo(rectWidth + 5, 0); path.lineTo(rectWidth + 5, size.height); canvas.drawPath(path, _paint); // 总长 2m double step = (rectWidth / aimcontroller.plot.value / 10).roundToDouble(); canvas.translate(rectWidth + 5, rectWidth + 5); for (var i = 0; i < 21; i++) { if (i % 10 == 0) { double line = 7; canvas.drawLine(Offset(0, i * step), Offset(line, i * step), _paint); canvas.drawLine(Offset(i * step, 0), Offset(i * step, line), _paint); canvas.drawLine(Offset(0, -i * step), Offset(line, -i * step), _paint); canvas.drawLine(Offset(-i * step, 0), Offset(-i * step, line), _paint); drawText(canvas, Offset(line, i * step), -i ~/ 10); drawText(canvas, Offset(line, -i * step), (i ~/ 10)); if (i ~/ 10 != 0) { drawText(canvas, Offset(i * step, line), i ~/ 10); drawText(canvas, Offset(-i * step, line), (-i ~/ 10)); } } else if (i % 5 == 0) { double line = 5; canvas.drawLine(Offset(0, i * step), Offset(line, i * step), _paint); canvas.drawLine(Offset(i * step, 0), Offset(i * step, line), _paint); canvas.drawLine(Offset(0, -i * step), Offset(line, -i * step), _paint); canvas.drawLine(Offset(-i * step, 0), Offset(-i * step, line), _paint); } else { double line = 3; canvas.drawLine(Offset(0, i * step), Offset(line, i * step), _paint); canvas.drawLine(Offset(i * step, 0), Offset(i * step, line), _paint); canvas.drawLine(Offset(0, -i * step), Offset(line, -i * step), _paint); canvas.drawLine(Offset(-i * step, 0), Offset(-i * step, line), _paint); } } canvas.translate(-(rectWidth + 5), -(rectWidth + 5)); canvas.translate(rectWidth + 5, rectWidth + 5); if (aimcontroller.selectedPilePoint != null) { drawPoint(canvas); } // // 绘制水平仪 // double x = real.tiltX.value; // // double y = real.tiltY.value; // // print("----${real.centerX.value},${real.centerY.value}"); // if (real.tiltX.value == 0 || real.tiltY.value == 0) { // x = 0; // y = 0; // } // _paint.color = Colors.red; // canvas.drawCircle(Offset(x * step * 10, y * step * 10), 10, _paint); // canvas.translate(-(rectWidth + 5), -(rectWidth + 5)); } drawText(Canvas canvas, Offset offset, int i, [bool isShow = true]) { TextPainter textPainter = TextPainter( text: TextSpan( text: isShow ? "$i m" : "$i", style: TextStyle( fontSize: 12, color: isDarkMode ? Colors.white : Colors.black)), textDirection: TextDirection.ltr, textAlign: TextAlign.left); textPainter.layout(); textPainter.paint(canvas, offset); } drawPoint(Canvas canvas) { canvas.drawCircle(Offset.zero, 20, Paint()..color = const Color.fromARGB(255, 139, 33, 33)); // drawText(canvas, pos - const Offset(20, 10), i, false); } // drawRect(Canvas canvas, double rectWidth) { // double x = item.dx - real.centerX.value; // double y = item.dy - real.centerY.value; // Offset center = Offset(x, y); // canvas.drawRect( // Rect.fromCenter(center: center, width: rectWidth, height: rectWidth), // _paint); // } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => true; } // 瞄准器卡片 class SightGview extends StatelessWidget { const SightGview(); @override Widget build(BuildContext context) { final Size size = MediaQuery.of(context).size; MediaQueryData mediaQueryData = MediaQueryData.fromView(WidgetsBinding.instance.window); //获取当前屏幕信息 final orientation = mediaQueryData.orientation; //获得设备方向 double rectWidth = size.width; final deviceType = getDeviceType(context); if (orientation == Orientation.landscape) { rectWidth = size.width / 2 - 60; if (deviceType == DeviceType.mobile) { rectWidth = size.height - 130; } } else { rectWidth = size.height / 2; if (deviceType == DeviceType.mobile) { rectWidth = size.width - 5; } } return Obx(() => Visibility( visible: aimcontroller.isCardVisible.value, child: Positioned( left: aimcontroller.sightOffset.value.dx, top: aimcontroller.sightOffset.value.dy, width: rectWidth + 15, height: rectWidth + 15, child: GestureDetector( onScaleStart: (details) { // 正确计算初始偏移量:当前手指位置与卡片当前位置之间的差值 aimcontroller.sightInit.value = details.localFocalPoint - aimcontroller.sightOffset.value; // // // print( 'aimcontroller.isCardVisible: ${aimcontroller.isCardVisible.value}'); }, onScaleUpdate: (details) { // 使用初始偏移量来更新卡片的位置 aimcontroller.sightOffset.value = details.localFocalPoint - aimcontroller.sightInit.value; }, child: Container( decoration: const BoxDecoration(color: Colors.transparent), child: Stack(children: [ Card( color: Colors.transparent, elevation: 5.0, child: AimPointer(), ), ])))))); } }