gc-wing/apps/web/src/widgets/map3d/lib/globeShipIcon.ts

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
}
}