77 lines
1.9 KiB
TypeScript
77 lines
1.9 KiB
TypeScript
import maplibregl from 'maplibre-gl';
|
|
|
|
export function buildFallbackGlobeShipIcon() {
|
|
const size = 96;
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = size;
|
|
canvas.height = size;
|
|
const ctx = canvas.getContext('2d');
|
|
if (!ctx) return null;
|
|
|
|
ctx.clearRect(0, 0, size, size);
|
|
ctx.fillStyle = 'rgba(255,255,255,1)';
|
|
ctx.beginPath();
|
|
ctx.moveTo(size / 2, 6);
|
|
ctx.lineTo(size / 2 - 14, 24);
|
|
ctx.lineTo(size / 2 - 18, 58);
|
|
ctx.lineTo(size / 2 - 10, 88);
|
|
ctx.lineTo(size / 2 + 10, 88);
|
|
ctx.lineTo(size / 2 + 18, 58);
|
|
ctx.lineTo(size / 2 + 14, 24);
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
|
|
ctx.fillRect(size / 2 - 8, 34, 16, 18);
|
|
|
|
return ctx.getImageData(0, 0, size, size);
|
|
}
|
|
|
|
export function buildFallbackGlobeAnchoredShipIcon() {
|
|
const baseImage = buildFallbackGlobeShipIcon();
|
|
if (!baseImage) return null;
|
|
|
|
const size = baseImage.width;
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = size;
|
|
canvas.height = size;
|
|
const ctx = canvas.getContext('2d');
|
|
if (!ctx) return null;
|
|
|
|
ctx.putImageData(baseImage, 0, 0);
|
|
|
|
ctx.strokeStyle = 'rgba(248,250,252,1)';
|
|
ctx.lineWidth = 5;
|
|
ctx.lineCap = 'round';
|
|
ctx.beginPath();
|
|
const cx = size / 2;
|
|
ctx.moveTo(cx - 18, 76);
|
|
ctx.lineTo(cx + 18, 76);
|
|
ctx.moveTo(cx, 66);
|
|
ctx.lineTo(cx, 82);
|
|
ctx.moveTo(cx, 82);
|
|
ctx.arc(cx, 82, 7, 0, Math.PI * 2);
|
|
ctx.moveTo(cx, 82);
|
|
ctx.lineTo(cx, 88);
|
|
ctx.moveTo(cx - 9, 88);
|
|
ctx.lineTo(cx + 9, 88);
|
|
ctx.stroke();
|
|
|
|
return ctx.getImageData(0, 0, size, size);
|
|
}
|
|
|
|
export function ensureFallbackShipImage(
|
|
map: maplibregl.Map,
|
|
imageId: string,
|
|
fallbackBuilder: () => ImageData | null = buildFallbackGlobeShipIcon,
|
|
) {
|
|
if (!map || map.hasImage(imageId)) return;
|
|
const image = fallbackBuilder();
|
|
if (!image) return;
|
|
|
|
try {
|
|
map.addImage(imageId, image, { pixelRatio: 2, sdf: true });
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}
|