JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<h2>Leaflet Creeping Line Ahead Pattern</h2>
<!-- Create a div element to hold the map -->
<div id="map"></div>
<select id="tests" style="position: absolute; top:1em; right:0">
<option selected value="bottom,left,90,left">(bottom-left) -> right</option>
<option value="bottom,left,0,right">(bottom-left) -> up</option>
<option value="top,left,90,right">(top-left) -> right</option>
<option value="top,left,180,left">(top-left) -> down</option>
<option value="bottom,right,-90,right">(bottom-right) -> left</option>
<option value="bottom,right,0,left">(bottom-right) -> up</option>
<option value="top,right,-90,left">(top-right) -> left</option>
<option value="top,right,180,right">(top-right) -> down</option>
</select>
CSS
#map {
height: 500px;
width: 100%;
}
JavaScript
// Initialize the map and set its view to a given location and zoom level
const map = L.map('map').setView([9.5415, 35.2651], 14);
// Add an OpenStreetMap layer to the map
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
const _bottom = 9.531347, // min latitude
_top = 9.552678, // max latitude
_left = 35.25444, // min longitude
_right = 35.27577; // max longitude
// Define the coordinates of the rectangle
const rectangleCoords = [
[_bottom, _left], // bottom-left corner (latitude, longitude)
[_top, _left], // top-left corner (latitude, longitude)
[_top, _right], // top-right corner (latitude, longitude)
[_bottom, _right] // bottom-right corner (latitude, longitude)
];
// Create a polygon (rectangle) using the provided coordinates
const rectangle = L.polygon(rectangleCoords, {
color: 'blue', // Color of the rectangle border
weight: 0.5, // Thickness of the rectangle border
fillColor: 'blue', // Fill color of the rectangle
fillOpacity: 0.2 // Opacity of the fill color
}).addTo(map);
const MAX_LINES = 1000; // safety, to prevent infinite loop
let claPath = null, circleEntry = null, circleExit = null;
function drawCLA(csp, initialHeading, firstTurn, trackSpacing = 0.0004, distanceFromEdge = 0.0005){
// Draw the creeping line ahead pattern inside the rectangle
claPath?.remove();
circleEntry?.remove();
circleExit?.remove();
const polyLine = computeCLAPolyline(rectangle.getBounds(), csp,
initialHeading, firstTurn, trackSpacing, distanceFromEdge);
if(polyLine.length === 0){
return;
}
claPath = L.polyline(polyLine, {color: 'gray', weight: 2});
claPath.addTo(map);
// entry point
circleEntry = L.circle(polyLine[0], 30, {color: 'green', fillColor: 'green', fillOpacity: 1});
circleEntry.addTo(map);
// exit point
...