diff --git a/lib/src/layer/polyline_layer.dart b/lib/src/layer/polyline_layer.dart index d443b3d68..9ef69493d 100644 --- a/lib/src/layer/polyline_layer.dart +++ b/lib/src/layer/polyline_layer.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:ui'; import 'package:flutter/widgets.dart'; @@ -15,10 +16,16 @@ class Polyline { final List offsets = []; final double strokeWidth; final Color color; + final double borderStrokeWidth; + final Color borderColor; + final bool isDotted; Polyline({ this.points, this.strokeWidth = 1.0, this.color = const Color(0xFF00FF00), + this.borderStrokeWidth = 0.0, + this.borderColor = const Color(0xFFFFFF00), + this.isDotted = false, }); } @@ -88,9 +95,65 @@ class PolylinePainter extends CustomPainter { final paint = new Paint() ..color = polylineOpt.color ..strokeWidth = polylineOpt.strokeWidth; - canvas.drawPoints(PointMode.lines, polylineOpt.offsets, paint); + final borderPaint = polylineOpt.borderStrokeWidth > 0.0 + ? (new Paint() + ..color = polylineOpt.borderColor + ..strokeWidth = polylineOpt.strokeWidth + polylineOpt.borderStrokeWidth) + : null; + double radius = polylineOpt.strokeWidth / 2; + double borderRadius = radius + (polylineOpt.borderStrokeWidth / 2); + if (polylineOpt.isDotted) { + double spacing = polylineOpt.strokeWidth * 1.5; + if (borderPaint != null) { + _paintDottedLine(canvas, polylineOpt.offsets, borderRadius, spacing, borderPaint); + } + _paintDottedLine(canvas, polylineOpt.offsets, radius, spacing, paint); + } else { + if (borderPaint != null) { + _paintLine(canvas, polylineOpt.offsets, borderRadius, borderPaint); + } + _paintLine(canvas, polylineOpt.offsets, radius, paint); + } + } + + void _paintDottedLine(Canvas canvas, List offsets, double radius, double stepLength, Paint paint) { + double startDistance = 0.0; + for (int i = 0; i < offsets.length - 1; i++) { + Offset o0 = offsets[i]; + Offset o1 = offsets[i + 1]; + double totalDistance = _dist(o0, o1); + double distance = startDistance; + while (distance < totalDistance) { + double f1 = distance / totalDistance; + double f0 = 1.0 - f1; + var offset = Offset(o0.dx * f0 + o1.dx * f1, o0.dy * f0 + o1.dy * f1); + canvas.drawCircle(offset, radius, paint); + distance += stepLength; + } + startDistance = distance < totalDistance ? stepLength - (totalDistance - distance) : distance - totalDistance; + } + canvas.drawCircle(polylineOpt.offsets.last, radius, paint); + } + + void _paintLine(Canvas canvas, List offsets, double radius, Paint paint) { + canvas.drawPoints(PointMode.lines, offsets, paint); + for (var offset in offsets) { + canvas.drawCircle(offset, radius, paint); + } } @override bool shouldRepaint(PolylinePainter other) => false; } + +double _dist(Offset v, Offset w) { + return sqrt(_dist2(v, w)); +} + +double _dist2(Offset v, Offset w) { + return _sqr(v.dx - w.dx) + _sqr(v.dy - w.dy); +} + +double _sqr(double x) { + return x * x; +}