@bitalltech-maplibre/core 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +344 -297
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +287 -7
- package/dist/index.umd.js +1 -1
- package/dist/types/__tests__/radar-power-group.test.d.ts +1 -0
- package/dist/types/effects/index.d.ts +2 -0
- package/dist/types/effects/low-altitude.d.ts +2 -0
- package/dist/types/effects/radar-power-group.d.ts +89 -0
- package/dist/types/index.d.ts +2 -2
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -293,6 +293,273 @@ const createBeamGeometry = (options) => {
|
|
|
293
293
|
}
|
|
294
294
|
};
|
|
295
295
|
};
|
|
296
|
+
const EMPTY_FEATURE_COLLECTION = {
|
|
297
|
+
type: "FeatureCollection",
|
|
298
|
+
features: []
|
|
299
|
+
};
|
|
300
|
+
const createFeature$1 = (geometry, properties) => ({
|
|
301
|
+
type: "Feature",
|
|
302
|
+
geometry,
|
|
303
|
+
properties
|
|
304
|
+
});
|
|
305
|
+
const asOpacity = (value, fallback) => Math.max(0, Math.min(1, value ?? fallback));
|
|
306
|
+
const createRadarPowerFeatures = (radar) => {
|
|
307
|
+
var _a;
|
|
308
|
+
if (radar.visible === false) {
|
|
309
|
+
return [];
|
|
310
|
+
}
|
|
311
|
+
const color = radar.color ?? "#38ff4a";
|
|
312
|
+
const ringColor = radar.ringColor ?? color;
|
|
313
|
+
const ringCount = Math.max(0, Math.floor(radar.ringCount ?? 4));
|
|
314
|
+
const coreRadius = Math.max(20, radar.coreRadius ?? Math.min(160, radar.radius * 0.035));
|
|
315
|
+
const features = [];
|
|
316
|
+
if (radar.fillOpacity && radar.fillOpacity > 0) {
|
|
317
|
+
features.push(
|
|
318
|
+
createFeature$1(createCirclePolygon(radar.center, radar.radius), {
|
|
319
|
+
radarId: radar.id,
|
|
320
|
+
kind: "fill",
|
|
321
|
+
color: radar.fillColor ?? color,
|
|
322
|
+
opacity: asOpacity(radar.fillOpacity, 0)
|
|
323
|
+
})
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
for (let index = ringCount; index >= 1; index -= 1) {
|
|
327
|
+
const distance = radar.radius * index / ringCount;
|
|
328
|
+
features.push(
|
|
329
|
+
createFeature$1(createCircleLine(radar.center, distance), {
|
|
330
|
+
radarId: radar.id,
|
|
331
|
+
kind: "ring",
|
|
332
|
+
color: ringColor,
|
|
333
|
+
opacity: asOpacity(radar.ringOpacity, 0.95),
|
|
334
|
+
width: Math.max(0, radar.ringWidth ?? 2)
|
|
335
|
+
})
|
|
336
|
+
);
|
|
337
|
+
if (radar.showDistanceLabels !== false) {
|
|
338
|
+
const text = ((_a = radar.distanceLabelFormatter) == null ? void 0 : _a.call(radar, distance, index)) ?? `${Math.round(distance)}`;
|
|
339
|
+
[
|
|
340
|
+
{ bearing: 0, textAnchor: "bottom" },
|
|
341
|
+
{ bearing: 90, textAnchor: "left" },
|
|
342
|
+
{ bearing: 180, textAnchor: "top" },
|
|
343
|
+
{ bearing: 270, textAnchor: "right" }
|
|
344
|
+
].forEach((label) => {
|
|
345
|
+
features.push(
|
|
346
|
+
createFeature$1(
|
|
347
|
+
{
|
|
348
|
+
type: "Point",
|
|
349
|
+
coordinates: getDestination(radar.center, distance, label.bearing)
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
radarId: radar.id,
|
|
353
|
+
kind: "distance-label",
|
|
354
|
+
text,
|
|
355
|
+
textAnchor: label.textAnchor,
|
|
356
|
+
color: radar.distanceLabelColor ?? ringColor,
|
|
357
|
+
opacity: asOpacity(radar.distanceLabelOpacity, 0.92),
|
|
358
|
+
haloColor: radar.distanceLabelHaloColor ?? "rgba(15, 23, 42, 0.42)",
|
|
359
|
+
size: radar.distanceLabelSize ?? 12
|
|
360
|
+
}
|
|
361
|
+
)
|
|
362
|
+
);
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (radar.showCrosshair !== false) {
|
|
367
|
+
features.push(
|
|
368
|
+
createFeature$1(
|
|
369
|
+
{
|
|
370
|
+
type: "LineString",
|
|
371
|
+
coordinates: [
|
|
372
|
+
getDestination(radar.center, radar.radius, 180),
|
|
373
|
+
getDestination(radar.center, radar.radius, 0)
|
|
374
|
+
]
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
radarId: radar.id,
|
|
378
|
+
kind: "crosshair",
|
|
379
|
+
color: radar.crosshairColor ?? ringColor,
|
|
380
|
+
opacity: asOpacity(radar.crosshairOpacity, 0.5),
|
|
381
|
+
width: Math.max(0, radar.crosshairWidth ?? 1.4)
|
|
382
|
+
}
|
|
383
|
+
),
|
|
384
|
+
createFeature$1(
|
|
385
|
+
{
|
|
386
|
+
type: "LineString",
|
|
387
|
+
coordinates: [
|
|
388
|
+
getDestination(radar.center, radar.radius, 270),
|
|
389
|
+
getDestination(radar.center, radar.radius, 90)
|
|
390
|
+
]
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
radarId: radar.id,
|
|
394
|
+
kind: "crosshair",
|
|
395
|
+
color: radar.crosshairColor ?? ringColor,
|
|
396
|
+
opacity: asOpacity(radar.crosshairOpacity, 0.5),
|
|
397
|
+
width: Math.max(0, radar.crosshairWidth ?? 1.4)
|
|
398
|
+
}
|
|
399
|
+
)
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
features.push(
|
|
403
|
+
createFeature$1(createCirclePolygon(radar.center, coreRadius), {
|
|
404
|
+
radarId: radar.id,
|
|
405
|
+
kind: "core",
|
|
406
|
+
color: radar.coreColor ?? color,
|
|
407
|
+
opacity: asOpacity(radar.fillOpacity, 0)
|
|
408
|
+
})
|
|
409
|
+
);
|
|
410
|
+
return features;
|
|
411
|
+
};
|
|
412
|
+
const createRadarPowerData = (radars) => ({
|
|
413
|
+
type: "FeatureCollection",
|
|
414
|
+
features: radars.flatMap(createRadarPowerFeatures)
|
|
415
|
+
});
|
|
416
|
+
const createLayerDefinitions = (id) => {
|
|
417
|
+
const source = `${id}-source`;
|
|
418
|
+
const layers = [
|
|
419
|
+
{
|
|
420
|
+
id: `${id}-fill`,
|
|
421
|
+
type: "fill",
|
|
422
|
+
source,
|
|
423
|
+
filter: ["==", ["get", "kind"], "fill"],
|
|
424
|
+
paint: {
|
|
425
|
+
"fill-color": ["coalesce", ["get", "color"], "#38ff4a"],
|
|
426
|
+
"fill-opacity": ["coalesce", ["get", "opacity"], 0]
|
|
427
|
+
}
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
id: `${id}-core`,
|
|
431
|
+
type: "fill",
|
|
432
|
+
source,
|
|
433
|
+
filter: ["==", ["get", "kind"], "core"],
|
|
434
|
+
paint: {
|
|
435
|
+
"fill-color": ["coalesce", ["get", "color"], "#38ff4a"],
|
|
436
|
+
"fill-opacity": ["coalesce", ["get", "opacity"], 0]
|
|
437
|
+
}
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
id: `${id}-ring`,
|
|
441
|
+
type: "line",
|
|
442
|
+
source,
|
|
443
|
+
filter: ["==", ["get", "kind"], "ring"],
|
|
444
|
+
paint: {
|
|
445
|
+
"line-color": ["coalesce", ["get", "color"], "#38ff4a"],
|
|
446
|
+
"line-opacity": ["coalesce", ["get", "opacity"], 0.95],
|
|
447
|
+
"line-width": ["coalesce", ["get", "width"], 2]
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
id: `${id}-crosshair`,
|
|
452
|
+
type: "line",
|
|
453
|
+
source,
|
|
454
|
+
filter: ["==", ["get", "kind"], "crosshair"],
|
|
455
|
+
paint: {
|
|
456
|
+
"line-color": ["coalesce", ["get", "color"], "#38ff4a"],
|
|
457
|
+
"line-opacity": ["coalesce", ["get", "opacity"], 0.5],
|
|
458
|
+
"line-width": ["coalesce", ["get", "width"], 1.4]
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
id: `${id}-labels`,
|
|
463
|
+
type: "symbol",
|
|
464
|
+
source,
|
|
465
|
+
filter: ["==", ["get", "kind"], "distance-label"],
|
|
466
|
+
layout: {
|
|
467
|
+
"text-field": ["get", "text"],
|
|
468
|
+
"text-size": ["coalesce", ["get", "size"], 12],
|
|
469
|
+
"text-anchor": ["get", "textAnchor"],
|
|
470
|
+
"text-allow-overlap": true,
|
|
471
|
+
"text-ignore-placement": true
|
|
472
|
+
},
|
|
473
|
+
paint: {
|
|
474
|
+
"text-color": ["coalesce", ["get", "color"], "#38ff4a"],
|
|
475
|
+
"text-opacity": ["coalesce", ["get", "opacity"], 0.92],
|
|
476
|
+
"text-halo-color": ["coalesce", ["get", "haloColor"], "rgba(15, 23, 42, 0.42)"],
|
|
477
|
+
"text-halo-width": 1
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
];
|
|
481
|
+
return {
|
|
482
|
+
source,
|
|
483
|
+
layers
|
|
484
|
+
};
|
|
485
|
+
};
|
|
486
|
+
const removeLayerIfExists$1 = (map, id) => {
|
|
487
|
+
if (map.getLayer(id)) {
|
|
488
|
+
map.removeLayer(id);
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
const removeSourceIfExists$1 = (map, id) => {
|
|
492
|
+
if (map.getSource(id)) {
|
|
493
|
+
map.removeSource(id);
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
const addRadarPowerGroup = (map, options) => {
|
|
497
|
+
const { source, layers } = createLayerDefinitions(options.id);
|
|
498
|
+
let radars = [...options.radars ?? []];
|
|
499
|
+
let removed = false;
|
|
500
|
+
map.addSource(source, {
|
|
501
|
+
type: "geojson",
|
|
502
|
+
data: EMPTY_FEATURE_COLLECTION
|
|
503
|
+
});
|
|
504
|
+
layers.forEach((layer) => {
|
|
505
|
+
map.addLayer(layer, options.beforeId);
|
|
506
|
+
});
|
|
507
|
+
const sourceRef = map.getSource(source);
|
|
508
|
+
const layerIds = layers.map((layer) => layer.id);
|
|
509
|
+
const setGroupVisibility = (visible) => {
|
|
510
|
+
layerIds.forEach((layerId) => {
|
|
511
|
+
if (map.getLayer(layerId)) {
|
|
512
|
+
map.setLayoutProperty(layerId, "visibility", visible ? "visible" : "none");
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
};
|
|
516
|
+
const setData = (nextRadars) => {
|
|
517
|
+
if (removed) return;
|
|
518
|
+
radars = nextRadars.map((radar) => ({ ...radar }));
|
|
519
|
+
sourceRef.setData(createRadarPowerData(radars));
|
|
520
|
+
};
|
|
521
|
+
if (radars.length > 0) {
|
|
522
|
+
setData(radars);
|
|
523
|
+
}
|
|
524
|
+
if (options.visible === false) {
|
|
525
|
+
setGroupVisibility(false);
|
|
526
|
+
}
|
|
527
|
+
return {
|
|
528
|
+
id: options.id,
|
|
529
|
+
sourceId: source,
|
|
530
|
+
layerIds,
|
|
531
|
+
setData,
|
|
532
|
+
updateRadar(id, nextOptions) {
|
|
533
|
+
const index = radars.findIndex((radar) => radar.id === id);
|
|
534
|
+
if (index < 0 || removed) return;
|
|
535
|
+
radars[index] = { ...radars[index], ...nextOptions, id };
|
|
536
|
+
sourceRef.setData(createRadarPowerData(radars));
|
|
537
|
+
},
|
|
538
|
+
setRadarVisible(id, visible) {
|
|
539
|
+
const radar = radars.find((item) => item.id === id);
|
|
540
|
+
if (!radar || removed) return;
|
|
541
|
+
radar.visible = visible;
|
|
542
|
+
sourceRef.setData(createRadarPowerData(radars));
|
|
543
|
+
},
|
|
544
|
+
removeRadar(id) {
|
|
545
|
+
if (removed) return;
|
|
546
|
+
radars = radars.filter((radar) => radar.id !== id);
|
|
547
|
+
sourceRef.setData(createRadarPowerData(radars));
|
|
548
|
+
},
|
|
549
|
+
show() {
|
|
550
|
+
if (!removed) setGroupVisibility(true);
|
|
551
|
+
},
|
|
552
|
+
hide() {
|
|
553
|
+
if (!removed) setGroupVisibility(false);
|
|
554
|
+
},
|
|
555
|
+
remove() {
|
|
556
|
+
if (removed) return;
|
|
557
|
+
removed = true;
|
|
558
|
+
[...layerIds].reverse().forEach((layerId) => removeLayerIfExists$1(map, layerId));
|
|
559
|
+
removeSourceIfExists$1(map, source);
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
};
|
|
296
563
|
const createFeature = (geometry, properties) => ({
|
|
297
564
|
type: "Feature",
|
|
298
565
|
geometry,
|
|
@@ -398,7 +665,8 @@ const createManagedEffect = (map, initialOptions, renderEffect) => {
|
|
|
398
665
|
if (nextRender.startAnimation) {
|
|
399
666
|
disposeAnimation = nextRender.startAnimation({
|
|
400
667
|
getOptions: () => options,
|
|
401
|
-
setData
|
|
668
|
+
setData,
|
|
669
|
+
requestRender: () => map.triggerRepaint()
|
|
402
670
|
}) || void 0;
|
|
403
671
|
}
|
|
404
672
|
};
|
|
@@ -909,7 +1177,8 @@ const createSectorScanRender = (options) => {
|
|
|
909
1177
|
options.center,
|
|
910
1178
|
options.radius
|
|
911
1179
|
),
|
|
912
|
-
|
|
1180
|
+
// 动画由插件主动 triggerRepaint,避免 CanvasSource 自己持续刷新一整张地图。
|
|
1181
|
+
animate: false
|
|
913
1182
|
}
|
|
914
1183
|
}
|
|
915
1184
|
] : void 0,
|
|
@@ -926,16 +1195,26 @@ const createSectorScanRender = (options) => {
|
|
|
926
1195
|
}
|
|
927
1196
|
}
|
|
928
1197
|
],
|
|
929
|
-
startAnimation: options.rotationSpeed && options.rotationSpeed !== 0 ? ({ getOptions, setData }) => {
|
|
1198
|
+
startAnimation: options.rotationSpeed && options.rotationSpeed !== 0 ? ({ getOptions, setData, requestRender }) => {
|
|
930
1199
|
const startTime = performance.now();
|
|
931
1200
|
let frameId = 0;
|
|
1201
|
+
let lastFrameTime = -Infinity;
|
|
932
1202
|
const tick = (timestamp) => {
|
|
933
1203
|
const currentOptions = getOptions();
|
|
934
|
-
const
|
|
935
|
-
|
|
936
|
-
|
|
1204
|
+
const frameRate = currentOptions.frameRate ?? 30;
|
|
1205
|
+
const minFrameInterval = frameRate > 0 ? 1e3 / frameRate : 0;
|
|
1206
|
+
if (timestamp - lastFrameTime >= minFrameInterval) {
|
|
1207
|
+
const angleOffset = (timestamp - startTime) / 1e3 * (currentOptions.rotationSpeed || 0);
|
|
1208
|
+
const outlineVisible = (currentOptions.outlineOpacity ?? 0.95) > 0 && (currentOptions.outlineWidth ?? 2) > 0;
|
|
1209
|
+
if (canvas) {
|
|
1210
|
+
drawSectorGradientCanvas(canvas, currentOptions, angleOffset);
|
|
1211
|
+
requestRender();
|
|
1212
|
+
}
|
|
1213
|
+
if (!canvas || outlineVisible) {
|
|
1214
|
+
setData(createSectorScanData(currentOptions, angleOffset));
|
|
1215
|
+
}
|
|
1216
|
+
lastFrameTime = timestamp;
|
|
937
1217
|
}
|
|
938
|
-
setData(createSectorScanData(currentOptions, angleOffset));
|
|
939
1218
|
frameId = requestAnimationFrame(tick);
|
|
940
1219
|
};
|
|
941
1220
|
frameId = requestAnimationFrame(tick);
|
|
@@ -3906,6 +4185,7 @@ export {
|
|
|
3906
4185
|
addDirectionalPulse,
|
|
3907
4186
|
addNavigationSpoofing,
|
|
3908
4187
|
addPulseMarker,
|
|
4188
|
+
addRadarPowerGroup,
|
|
3909
4189
|
addRadarSweep,
|
|
3910
4190
|
addRingPulseMarker,
|
|
3911
4191
|
addSectorScan,
|