pile_nav_new/lib/pages/aim_point/aimpoint_page.dart
tanlinxing 58ec37a7c5 CFG
2024-11-21 10:01:14 +08:00

394 lines
16 KiB
Dart

import 'dart:math';
import 'dart:ui' as ui;
import 'dart:developer' as dev;
import 'package:flutter/material.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 'aimpoint_controller.dart';
final AimPointerController aimcontroller = Get.find<AimPointerController>();
final ScenceMapController mapcontroller = Get.find<ScenceMapController>();
final GnssController gnsscontroller = Get.find<GnssController>();
// ignore: must_be_immutable
class AimPointer extends GetView<AimPointerController> {
String gradienter = "0";
final Size size;
AimPointer({super.key, required this.size}); //水平仪
@override
Widget build(BuildContext context) {
final mediaQueryData = MediaQueryData.fromView(View.of(context)); //获取当前屏幕信息
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 - 60;
// }
// } else {
// rectWidth = size.height / 2;
// if (deviceType == DeviceType.mobile) {
// rectWidth = size.width - 5;
// }
// }
bool isDarkMode = Theme.of(context).brightness == Brightness.dark;
List<Widget> children = [
SizedBox(
width: rectWidth,
height: rectWidth,
child: Card(
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
side: const BorderSide(color: Colors.transparent, width: 0),
borderRadius: BorderRadius.circular(4.0), // 可以根据需要调整圆角半径
),
child: 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: 30,
// right: 10,
// child: TextButton(
// child: Text(
// "垂直度:$gradienter°",
// style: const TextStyle(fontSize: 20),
// ),
// onPressed: () {},
// )),
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);
// if (dx * dy < 0) {
// 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.x.value =
dx * cos(-mapcontroller.rotation.value) +
dy * sin(-mapcontroller.rotation.value);
aimcontroller.y.value =
-dx * sin(-mapcontroller.rotation.value) +
dy * cos(-mapcontroller.rotation.value);
// aimcontroller.positionUpdate.value++;
dev.log("dx:$dx,dy:$dy");
dev.log(
"left:${aimcontroller.x.value},top:${aimcontroller.y.value}");
}
return Positioned(
left: rectWidth / 2 -
30 +
aimcontroller.y.value / pixel2MeterRatio,
top: rectWidth / 2 -
30 -
aimcontroller.x.value / pixel2MeterRatio,
child: Transform(
transform: Matrix4.identity()
..rotateZ(
gnsscontroller.device.rotation.value +
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 const 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<IconData> icons = [
Icons.arrow_drop_up,
Icons.arrow_drop_down,
Icons.arrow_left,
Icons.arrow_right
];
// List<Offset> iconOffset = [];
List<String> 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);
drawPoint(canvas);
// // 绘制水平仪
// double x = real.tiltX.value; //
// double y = real.tiltY.value; //
// log("----${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 ui.Color.fromARGB(129, 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({super.key, required this.size});
final Size size;
@override
Widget build(BuildContext context) {
final mediaQueryData = MediaQueryData.fromView(View.of(context)); //获取当前屏幕信息
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:
Stack(children: [
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;
},
onScaleUpdate: (details) {
// 使用初始偏移量来更新卡片的位置
aimcontroller.sightOffset.value =
details.localFocalPoint - aimcontroller.sightInit.value;
},
child: Stack(children: [
Container(
decoration:
const BoxDecoration(color: Colors.transparent),
child: Stack(children: [
Card(
color: Colors.transparent,
elevation: 5.0,
child: AimPointer(size: Size(rectWidth, rectWidth)),
),
])),
Positioned(
right: 10,
top: 5,
child: IconButton(
icon: const Icon(Icons.close),
onPressed: () {
// 关闭按钮的回调函数
aimcontroller.isCardVisible.value = false;
aimcontroller.lastCloseTapTime =
DateTime.now().millisecondsSinceEpoch;
},
),
)
]))),])
));
}
}