import 'dart:math' as math; import 'package:flutter/material.dart'; /// Live-Positionsmarker der Drohne im Fly-Modus (Doku 3.10), Papierflieger- /// Form aus design/B_paperplane.svg - nativ als [CustomPainter] statt als /// SVG-Asset nachgebaut (Format bewusst geaendert: die drei Pfade sind /// einfache Dreiecke, eine zusaetzliche SVG-Renderer-Abhaengigkeit lohnt sich /// dafuer nicht, siehe auch mountain_peak_icon.dart/wind_arrow_icon.dart fuer /// dasselbe Muster). Zeigt unrotiert (Spitze nach oben) bei fehlendem /// [headingDeg], sonst im Uhrzeigersinn um den Kurs ueber Grund gedreht. class DroneMarkerIcon extends StatelessWidget { const DroneMarkerIcon({super.key, this.size = 28, this.headingDeg}); final double size; /// Kurs ueber Grund in Grad (0 = Norden, im Uhrzeigersinn) aus /// TelemetryFrame.headingDeg. final double? headingDeg; @override Widget build(BuildContext context) { return Transform.rotate( angle: (headingDeg ?? 0) * math.pi / 180, child: CustomPaint( size: Size.square(size), painter: const _PaperPlanePainter(), ), ); } } class _PaperPlanePainter extends CustomPainter { const _PaperPlanePainter(); // 1:1 aus design/B_paperplane.svg uebernommene Koordinaten (viewBox // 0 0 200 200): Spitze oben, zwei Fluegel unten, Heckkerbe dazwischen. static const _viewBoxSize = 200.0; static const _nose = Offset(100, 22); static const _rightWing = Offset(164, 172); static const _tailNotch = Offset(100, 138); static const _leftWing = Offset(36, 172); static const _rightFill = Color(0xFFFF2E93); static const _leftFill = Color(0xFFB01464); static const _strokeWidth = 7.0; @override void paint(Canvas canvas, Size size) { final scale = size.width / _viewBoxSize; Offset s(Offset p) => p * scale; final rightHalf = Path() ..moveTo(s(_nose).dx, s(_nose).dy) ..lineTo(s(_rightWing).dx, s(_rightWing).dy) ..lineTo(s(_tailNotch).dx, s(_tailNotch).dy) ..close(); final leftHalf = Path() ..moveTo(s(_nose).dx, s(_nose).dy) ..lineTo(s(_leftWing).dx, s(_leftWing).dy) ..lineTo(s(_tailNotch).dx, s(_tailNotch).dy) ..close(); canvas.drawPath(rightHalf, Paint()..color = _rightFill); canvas.drawPath(leftHalf, Paint()..color = _leftFill); final outline = Path() ..moveTo(s(_nose).dx, s(_nose).dy) ..lineTo(s(_rightWing).dx, s(_rightWing).dy) ..lineTo(s(_tailNotch).dx, s(_tailNotch).dy) ..lineTo(s(_leftWing).dx, s(_leftWing).dy) ..close(); canvas.drawPath( outline, Paint() ..color = Colors.white ..style = PaintingStyle.stroke ..strokeWidth = _strokeWidth * scale ..strokeJoin = StrokeJoin.round, ); } @override bool shouldRepaint(covariant _PaperPlanePainter oldDelegate) => false; }