打点优化
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CrosshairPainter extends CustomPainter {
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
// 十字中心坐标(精准对齐容器中心)
|
||||
final centerX = size.width / 2;
|
||||
final centerY = size.height / 2;
|
||||
|
||||
// 十字画笔样式(红色醒目,匹配原有定位标风格)
|
||||
final paint = Paint()
|
||||
..color = Colors.red
|
||||
..strokeWidth =
|
||||
2.0 // 十字线条宽度
|
||||
..strokeCap = StrokeCap.round; // 线条端点圆润,更美观
|
||||
|
||||
// ========== 绘制水平横线(─) ==========
|
||||
canvas.drawLine(
|
||||
Offset(0, centerY), // 左端点
|
||||
Offset(size.width, centerY), // 右端点
|
||||
paint,
|
||||
);
|
||||
|
||||
// ========== 绘制垂直竖线(│) ==========
|
||||
canvas.drawLine(
|
||||
Offset(centerX, 0), // 上端点
|
||||
Offset(centerX, size.height), // 下端点
|
||||
paint,
|
||||
);
|
||||
|
||||
// 可选:中心小圆点(强化中心定位)
|
||||
final centerDotPaint = Paint()
|
||||
..color = Colors.white
|
||||
..style = PaintingStyle.fill;
|
||||
canvas.drawCircle(
|
||||
Offset(centerX, centerY),
|
||||
1.5, // 中心圆点半径
|
||||
centerDotPaint,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant CrosshairPainter oldDelegate) => false;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class HeadingMarkerPainter extends CustomPainter {
|
||||
final double headingAngle; // 航向角(度)
|
||||
|
||||
HeadingMarkerPainter({required this.headingAngle});
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
// 中心点坐标(对应SVG的cx=20, cy=20)
|
||||
final center = Offset(size.width / 2, size.height / 2);
|
||||
// 圆圈半径(对应SVG的r=10)
|
||||
final circleRadius = 10.0;
|
||||
|
||||
// ========== 1. 绘制绿色半透明圆圈(SVG的circle) ==========
|
||||
final circlePaint = Paint()
|
||||
..color = const Color(0xFF1AFA29)
|
||||
.withOpacity(0.7) // #1afa29 70%透明度
|
||||
..style = PaintingStyle.fill;
|
||||
canvas.drawCircle(center, circleRadius, circlePaint);
|
||||
|
||||
// 绘制白色描边(SVG的stroke="#fff" stroke-width="2")
|
||||
final strokePaint = Paint()
|
||||
..color = Colors.white
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 2.0;
|
||||
canvas.drawCircle(center, circleRadius, strokePaint);
|
||||
|
||||
// ========== 2. 绘制航向箭头(SVG的path) ==========
|
||||
// 保存画布状态(旋转后恢复)
|
||||
canvas.save();
|
||||
// 平移+旋转:以圆心为旋转中心,根据航向角旋转(对应SVG的transform)
|
||||
canvas.translate(center.dx, center.dy);
|
||||
canvas.rotate(headingAngle * pi / 180); // 角度转弧度
|
||||
|
||||
// 箭头路径(对应SVG的d="M0,-8 L4,4 L0,1 L-4,4 Z")
|
||||
final arrowPath = Path()
|
||||
..moveTo(0, -8) // 顶部顶点
|
||||
..lineTo(4, 4) // 右侧点
|
||||
..lineTo(0, 1) // 中下点
|
||||
..lineTo(-4, 4) // 左侧点
|
||||
..close(); // 闭合路径
|
||||
|
||||
final arrowPaint = Paint()..color = Colors.white;
|
||||
canvas.drawPath(arrowPath, arrowPaint);
|
||||
|
||||
// 恢复画布状态
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant HeadingMarkerPainter oldDelegate) {
|
||||
// 航向角变化时重新绘制
|
||||
return oldDelegate.headingAngle != headingAngle;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ import 'package:geolocator/geolocator.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:maibu_satabot_v2/features/home/presentation/widgets/BottomDirectionLine.dart';
|
||||
import 'package:maibu_satabot_v2/features/home/presentation/widgets/common/enum.dart';
|
||||
import 'package:maibu_satabot_v2/features/home/presentation/widgets/map/CenterLocation.dart';
|
||||
import 'package:maibu_satabot_v2/features/home/presentation/widgets/map/HeadingPointer.dart';
|
||||
import 'package:maibu_satabot_v2/features/home/presentation/widgets/startpoint_area.dart';
|
||||
|
||||
import '../path_list_pages.dart';
|
||||
@@ -33,6 +35,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
// ========== 核心新增状态 ==========
|
||||
List<LatLng> _markedPoints = []; // 存储所有打点坐标
|
||||
LatLng get _mapCenter => _mapController.center; // 实时获取地图中心坐标
|
||||
double _headingAngle = 0.0; // 航向角(单位:度)
|
||||
// =================================
|
||||
|
||||
@override
|
||||
@@ -150,18 +153,26 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
),
|
||||
|
||||
/// ========== 新增:中心标与历史打点的虚线连线 ==========
|
||||
///
|
||||
/// if (_markedPoints.length >= 2)
|
||||
PolylineLayer(
|
||||
polylines: [
|
||||
for (int i = 0; i < _markedPoints.length - 1; i++)
|
||||
Polyline(
|
||||
points: [_markedPoints[i], _markedPoints[i + 1]],
|
||||
color: Colors.orange.withOpacity(0.5),
|
||||
strokeWidth: 1.5,
|
||||
),
|
||||
],
|
||||
),
|
||||
if (_markedPoints.isNotEmpty)
|
||||
PolylineLayer(
|
||||
polylines: [
|
||||
for (var point in _markedPoints)
|
||||
Polyline(
|
||||
points: [_mapCenter, point], // 中心标 ↔ 历史打点
|
||||
color: Colors.orange.withOpacity(
|
||||
0.5,
|
||||
), // 降低透明度,模拟虚线视觉效果
|
||||
strokeWidth: 1.5, // 调细一点,更接近虚线
|
||||
// 去掉 dashArray,直接用实线
|
||||
),
|
||||
Polyline(
|
||||
points: [_mapCenter, _markedPoints.last],
|
||||
color: Colors.blue.withOpacity(0.5),
|
||||
strokeWidth: 1.5,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -171,12 +182,13 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
markers: [
|
||||
Marker(
|
||||
point: _currentLatLng!,
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: const Icon(
|
||||
Icons.my_location,
|
||||
color: Colors.blue,
|
||||
size: 30,
|
||||
width: 40,
|
||||
height: 40,
|
||||
child: CustomPaint(
|
||||
size: const Size(40, 40),
|
||||
painter: HeadingMarkerPainter(
|
||||
headingAngle: _headingAngle,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -195,6 +207,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const SizedBox(height: 8), // 向下偏移8px(抵消默认的顶部对齐)
|
||||
// 绿色打点标记
|
||||
Container(
|
||||
width: 16,
|
||||
@@ -226,21 +239,22 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
),
|
||||
|
||||
/// ========== 核心:地图正中心固定定位标 ==========
|
||||
const Positioned(
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.location_pin, // 定位标图标
|
||||
color: Colors.red, // 红色醒目
|
||||
size: 30,
|
||||
shadows: [BoxShadow(color: Colors.white, blurRadius: 2)],
|
||||
// 自定义十字标(中心精准对齐地图中心)
|
||||
child: SizedBox(
|
||||
width: 16, // 十字整体宽度
|
||||
height: 16, // 十字整体高度
|
||||
child: CustomPaint(
|
||||
painter: CrosshairPainter(), // 自定义十字画笔
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// 右侧悬浮菜单
|
||||
Positioned(
|
||||
height: 336,
|
||||
|
||||
Reference in New Issue
Block a user