diff --git a/src/components/WarMap.tsx b/src/components/WarMap.tsx index 4c5f9fc..3abc49b 100644 --- a/src/components/WarMap.tsx +++ b/src/components/WarMap.tsx @@ -656,26 +656,32 @@ export function WarMap() { }), [effectiveIsraelPaths] ) - /** 盟军打击目标点位(林肯/福特/以色列→伊朗+以色列→黎巴嫩),带衰减系数;全部/实时下按 effectiveCutoffDays 过滤 */ + /** 盟军打击目标点位(林肯/福特/以色列→伊朗+以色列→黎巴嫩)。全部/单项:显示全部目标;实时:仅 effectiveCutoffDays 内 */ const alliedStrikeTargetsFeatures = useMemo(() => { const out: GeoJSON.Feature[] = [] + const onlyRealtimeFilter = + strikeLegendFilter === null && isRealtimeView for (const line of strikeLines) { if (strikeLegendFilter != null && strikeLegendFilter !== 'lincoln' && strikeLegendFilter !== 'ford' && strikeLegendFilter !== 'israel') continue if (strikeLegendFilter === 'lincoln' && line.sourceId !== 'lincoln') continue if (strikeLegendFilter === 'ford' && line.sourceId !== 'ford') continue if (strikeLegendFilter === 'israel' && line.sourceId !== 'israel') continue for (const t of line.targets) { - if (!isWithinAnimationWindow(t.struck_at ?? null, referenceTime, effectiveCutoffDays)) continue - const decay = getDecayFactor(t.struck_at ?? null, referenceTime, effectiveCutoffDays) + if (onlyRealtimeFilter && !isWithinAnimationWindow((t as { struck_at?: string | null }).struck_at ?? null, referenceTime, effectiveCutoffDays)) + continue + const struckAt = (t as { struck_at?: string | null }).struck_at ?? null + const decay = onlyRealtimeFilter + ? getDecayFactor(struckAt, referenceTime, effectiveCutoffDays) + : 1 out.push({ type: 'Feature', - properties: { name: t.name ?? '', decay }, + properties: { name: (t as { name?: string }).name ?? '', decay }, geometry: { type: 'Point', coordinates: [t.lng, t.lat] }, }) } } return out - }, [strikeLines, referenceTime, strikeLegendFilter, effectiveCutoffDays]) + }, [strikeLines, referenceTime, strikeLegendFilter, isRealtimeView, effectiveCutoffDays]) const hezbollahLinesGeoJson = useMemo( () => ({ type: 'FeatureCollection' as const, @@ -856,7 +862,7 @@ export function WarMap() { const blink = 0.5 + 0.5 * Math.sin(elapsed * 0.003) map.setPaintProperty('points-damaged', 'circle-opacity', blink) } - // attacked: 红色脉冲,半径 = 基准×phase×zoomScale×decayScale(线性衰减) + // 脉冲:仅更新半径与透明度,颜色使用 Layer 默认(美军基地遭袭=红,盟军打击伊朗目标=蓝) if (map.getLayer('points-attacked-pulse')) { const cycle = 2000 const phase = Math.max(0, Math.min(1, (elapsed % cycle) / cycle)) @@ -955,7 +961,7 @@ export function WarMap() { }) hormuzSrc.setData({ type: 'FeatureCollection', features }) } - // 盟军打击目标:脉冲半径 = 基准×decayScale×zoomScale,线性衰减,镜头拉远半径变小 + // 盟军打击目标(伊朗境内等):脉冲动画,颜色保持 Layer 默认蓝 if (map.getLayer('allied-strike-targets-pulse')) { const cycle = 2000 const phase = Math.max(0, Math.min(1, (elapsed % cycle) / cycle)) @@ -1032,7 +1038,7 @@ export function WarMap() { const blink = 0.5 + 0.5 * Math.sin(elapsed * 0.004) map.setPaintProperty('gdelt-events-orange', 'circle-opacity', blink) } - // GDELT 红色:脉冲半径随 zoom×decayScale 线性变化 + // GDELT 高烈度:脉冲动画,颜色保持 Layer 默认 if (map.getLayer('gdelt-events-red-pulse')) { const cycle = 2200 const phase = Math.max(0, Math.min(1, (elapsed % cycle) / cycle)) @@ -1041,7 +1047,7 @@ export function WarMap() { map.setPaintProperty('gdelt-events-red-pulse', 'circle-radius', r) map.setPaintProperty('gdelt-events-red-pulse', 'circle-opacity', opacity) } - // 真主党攻击目标:脉冲半径衰减线性插值,镜头拉远变小 + // 真主党攻击目标:脉冲动画,颜色保持 Layer 默认 if (map.getLayer('hezbollah-attack-targets-pulse')) { const cycle = 2000 const phase = Math.max(0, Math.min(1, (elapsed % cycle) / cycle)) @@ -1050,7 +1056,7 @@ export function WarMap() { map.setPaintProperty('hezbollah-attack-targets-pulse', 'circle-radius', r) map.setPaintProperty('hezbollah-attack-targets-pulse', 'circle-opacity', opacity) } - // 霍尔木兹海峡被打击目标:脉冲半径随 zoom×decayScale + // 霍尔木兹海峡被打击目标:脉冲动画,颜色保持 Layer 默认 if (map.getLayer('iran-hormuz-targets-pulse')) { const cycle = 2000 const phase = Math.max(0, Math.min(1, (elapsed % cycle) / cycle))