fix:优化整个大屏界面
This commit is contained in:
@@ -3,7 +3,7 @@ import Map, { Source, Layer } from 'react-map-gl'
|
||||
import type { MapRef } from 'react-map-gl'
|
||||
import type { Map as MapboxMap } from 'mapbox-gl'
|
||||
import 'mapbox-gl/dist/mapbox-gl.css'
|
||||
import { useSituationStore } from '@/store/situationStore'
|
||||
import { useReplaySituation } from '@/hooks/useReplaySituation'
|
||||
import {
|
||||
ATTACKED_TARGETS,
|
||||
ALLIED_STRIKE_LOCATIONS,
|
||||
@@ -129,8 +129,8 @@ export function WarMap() {
|
||||
const lincolnPathsRef = useRef<[number, number][][]>([])
|
||||
const fordPathsRef = useRef<[number, number][][]>([])
|
||||
const israelPathsRef = useRef<[number, number][][]>([])
|
||||
const { situation } = useSituationStore()
|
||||
const { usForces, iranForces } = situation
|
||||
const situation = useReplaySituation()
|
||||
const { usForces, iranForces, conflictEvents = [] } = situation
|
||||
|
||||
const usLocs = (usForces.keyLocations || []) as KeyLoc[]
|
||||
const irLocs = (iranForces.keyLocations || []) as KeyLoc[]
|
||||
@@ -239,6 +239,29 @@ export function WarMap() {
|
||||
[attackPaths]
|
||||
)
|
||||
|
||||
// GDELT 冲突事件:1–3 绿, 4–6 橙闪, 7–10 红脉
|
||||
const { conflictEventsGreen, conflictEventsOrange, conflictEventsRed } = useMemo(() => {
|
||||
const green: GeoJSON.Feature<GeoJSON.Point>[] = []
|
||||
const orange: GeoJSON.Feature<GeoJSON.Point>[] = []
|
||||
const red: GeoJSON.Feature<GeoJSON.Point>[] = []
|
||||
for (const e of conflictEvents) {
|
||||
const score = e.impact_score ?? 1
|
||||
const f: GeoJSON.Feature<GeoJSON.Point> = {
|
||||
type: 'Feature',
|
||||
properties: { event_id: e.event_id, impact_score: score },
|
||||
geometry: { type: 'Point', coordinates: [e.lng, e.lat] },
|
||||
}
|
||||
if (score <= 3) green.push(f)
|
||||
else if (score <= 6) orange.push(f)
|
||||
else red.push(f)
|
||||
}
|
||||
return {
|
||||
conflictEventsGreen: { type: 'FeatureCollection' as const, features: green },
|
||||
conflictEventsOrange: { type: 'FeatureCollection' as const, features: orange },
|
||||
conflictEventsRed: { type: 'FeatureCollection' as const, features: red },
|
||||
}
|
||||
}, [conflictEvents])
|
||||
|
||||
const hideNonBelligerentLabels = (map: MapboxMap) => {
|
||||
const labelLayers = [
|
||||
'country-label',
|
||||
@@ -362,6 +385,20 @@ export function WarMap() {
|
||||
map.setPaintProperty('allied-strike-targets-pulse', 'circle-radius', r)
|
||||
map.setPaintProperty('allied-strike-targets-pulse', 'circle-opacity', opacity)
|
||||
}
|
||||
// GDELT 橙色 (4–6):闪烁
|
||||
if (map.getLayer('gdelt-events-orange')) {
|
||||
const blink = 0.5 + 0.5 * Math.sin(elapsed * 0.004)
|
||||
map.setPaintProperty('gdelt-events-orange', 'circle-opacity', blink)
|
||||
}
|
||||
// GDELT 红色 (7–10):脉冲扩散
|
||||
if (map.getLayer('gdelt-events-red-pulse')) {
|
||||
const cycle = 2200
|
||||
const phase = (elapsed % cycle) / cycle
|
||||
const r = 30 * phase
|
||||
const opacity = Math.max(0, 1 - phase * 1.1)
|
||||
map.setPaintProperty('gdelt-events-red-pulse', 'circle-radius', r)
|
||||
map.setPaintProperty('gdelt-events-red-pulse', 'circle-opacity', opacity)
|
||||
}
|
||||
} catch (_) {}
|
||||
animRef.current = requestAnimationFrame(tick)
|
||||
}
|
||||
@@ -376,7 +413,10 @@ export function WarMap() {
|
||||
(map.getSource('attack-dots') && attackPathsRef.current.length > 0) ||
|
||||
(map.getSource('allied-strike-dots-lincoln') && lincolnPathsRef.current.length > 0) ||
|
||||
(map.getSource('allied-strike-dots-ford') && fordPathsRef.current.length > 0) ||
|
||||
(map.getSource('allied-strike-dots-israel') && israelPathsRef.current.length > 0)
|
||||
(map.getSource('allied-strike-dots-israel') && israelPathsRef.current.length > 0) ||
|
||||
map.getSource('gdelt-events-green') ||
|
||||
map.getSource('gdelt-events-orange') ||
|
||||
map.getSource('gdelt-events-red')
|
||||
if (hasAnim) {
|
||||
animRef.current = requestAnimationFrame(tick)
|
||||
} else {
|
||||
@@ -439,6 +479,15 @@ export function WarMap() {
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-[#22D3EE]" /> 以色列打击
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-[#22C55E]" /> 低烈度
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-[#F97316]" /> 中烈度
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-[#EF4444]" /> 高烈度
|
||||
</span>
|
||||
</div>
|
||||
<Map
|
||||
ref={mapRef}
|
||||
@@ -537,6 +586,52 @@ export function WarMap() {
|
||||
/>
|
||||
</Source>
|
||||
|
||||
{/* GDELT 冲突事件:1–3 绿点, 4–6 橙闪, 7–10 红脉 */}
|
||||
<Source id="gdelt-events-green" type="geojson" data={conflictEventsGreen}>
|
||||
<Layer
|
||||
id="gdelt-events-green"
|
||||
type="circle"
|
||||
paint={{
|
||||
'circle-radius': ['interpolate', ['linear'], ['zoom'], 4, 2, 8, 4, 12, 6],
|
||||
'circle-color': '#22C55E',
|
||||
'circle-stroke-width': 0.5,
|
||||
'circle-stroke-color': '#fff',
|
||||
}}
|
||||
/>
|
||||
</Source>
|
||||
<Source id="gdelt-events-orange" type="geojson" data={conflictEventsOrange}>
|
||||
<Layer
|
||||
id="gdelt-events-orange"
|
||||
type="circle"
|
||||
paint={{
|
||||
'circle-radius': ['interpolate', ['linear'], ['zoom'], 4, 3, 8, 5, 12, 8],
|
||||
'circle-color': '#F97316',
|
||||
'circle-opacity': 0.8,
|
||||
}}
|
||||
/>
|
||||
</Source>
|
||||
<Source id="gdelt-events-red" type="geojson" data={conflictEventsRed}>
|
||||
<Layer
|
||||
id="gdelt-events-red-dot"
|
||||
type="circle"
|
||||
paint={{
|
||||
'circle-radius': ['interpolate', ['linear'], ['zoom'], 4, 2, 8, 4, 12, 6],
|
||||
'circle-color': '#EF4444',
|
||||
'circle-stroke-width': 0.5,
|
||||
'circle-stroke-color': '#fff',
|
||||
}}
|
||||
/>
|
||||
<Layer
|
||||
id="gdelt-events-red-pulse"
|
||||
type="circle"
|
||||
paint={{
|
||||
'circle-radius': 0,
|
||||
'circle-color': 'rgba(239, 68, 68, 0.5)',
|
||||
'circle-opacity': 0,
|
||||
}}
|
||||
/>
|
||||
</Source>
|
||||
|
||||
{/* 美以联军打击伊朗:路径线 */}
|
||||
<Source id="allied-strike-lines-lincoln" type="geojson" data={lincolnLinesGeoJson}>
|
||||
<Layer
|
||||
|
||||
Reference in New Issue
Block a user