Skip to content

Commit 32b359f

Browse files
Superhero-king杨乾
andauthored
✨feature: Optimize the Earth interaction experience (#46)
1. Optimize the material of the sphere to be more realistic 2. Use the `d3 geo` library to calculate the coordinate distance and optimize the height of the Bezier curve, making it more in line with the surface of the sphere Co-authored-by: 杨乾 <king473378347@gmail.com>
1 parent ad255be commit 32b359f

File tree

4 files changed

+41
-18
lines changed

4 files changed

+41
-18
lines changed

web/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"axios": "^1.8.4",
3939
"class-variance-authority": "^0.7.1",
4040
"clsx": "^2.1.1",
41+
"d3-geo": "^3.1.1",
4142
"date-fns": "^3.6.0",
4243
"echarts": "^5.6.0",
4344
"i18next": "^24.2.2",
@@ -57,13 +58,14 @@
5758
"tailwind-merge": "^2.6.0",
5859
"tailwindcss-animate": "^1.0.7",
5960
"three": "^0.176.0",
60-
"three-globe": "^2.42.4",
61+
"three-globe": "^2.42.8",
6162
"zod": "^3.24.1",
6263
"zustand": "^5.0.3"
6364
},
6465
"devDependencies": {
6566
"@eslint/js": "^9.17.0",
6667
"@tanstack/react-query-devtools": "^5.69.0",
68+
"@types/d3-geo": "^3.1.0",
6769
"@types/node": "^22.10.7",
6870
"@types/node-forge": "^1.3.11",
6971
"@types/react": "^18.3.18",

web/pnpm-lock.yaml

Lines changed: 18 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/src/feature/security-dashboard/component/SecurityDashboardLayout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Button } from '@/components/ui/button'
1212
import { OverviewStats } from '@/types/stats'
1313
import { AttackEventAggregateResult } from '@/types/log'
1414
import { useDebounce } from '@/hooks/useDebounce'
15+
import { geoDistance } from 'd3-geo';
1516

1617
/**
1718
* 安全大屏布局组件
@@ -145,7 +146,8 @@ export const SecurityDashboardLayout: React.FC = () => {
145146
startLng: event.srcIpInfo.location.longitude,
146147
endLat: 30.274084, // 杭州坐标
147148
endLng: 120.155070,
148-
arcAlt: Math.min(0.3, Math.max(0.05, event.count / 500)),
149+
// arcAlt: Math.min(0.3, Math.max(0.05, event.count / 500)),
150+
arcAlt: geoDistance([event.srcIpInfo.location.longitude, event.srcIpInfo.location.latitude], [120.155070, 30.274084]), // 计算起点和终点之间的地理距离(线条需要根据距离生成相应的贝塞尔曲线高度)
149151
colorIndex: Math.abs(event.srcIp.split('.').reduce((a, b) => a + parseInt(b), 0)) % 8 // 基于IP地址生成固定颜色索引
150152
}))
151153

web/src/feature/security-dashboard/component/globe3D-map/Globe3DMap.tsx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useEffect, useRef } from "react"
2-
import { WebGLRenderer, PerspectiveCamera, Scene, AmbientLight, DirectionalLight, Color, MeshStandardMaterial, FrontSide, PointLight } from "three"
2+
import { WebGLRenderer, PerspectiveCamera, Scene, AmbientLight, DirectionalLight, Color, PointLight, MeshPhysicalMaterial, DoubleSide } from "three"
33
import { OrbitControls } from "three/addons/controls/OrbitControls.js"
44
import ThreeGlobe from "three-globe"
55
import countries from "./globe-data-min.json"
@@ -138,7 +138,7 @@ const Globe3DMap = React.memo(({ wafAttackTrajectoryData }: { wafAttackTrajector
138138
// 创建新的Three.js实例
139139
const renderer = new WebGLRenderer({
140140
antialias: true,
141-
logarithmicDepthBuffer: false,
141+
logarithmicDepthBuffer: true,
142142
alpha: true,
143143
preserveDrawingBuffer: true // 保持绘制缓冲区
144144
})
@@ -189,19 +189,25 @@ const Globe3DMap = React.memo(({ wafAttackTrajectoryData }: { wafAttackTrajector
189189
const globe = new ThreeGlobe({ waitForGlobeReady: true, animateIn: true })
190190
scene.add(globe)
191191

192-
const globeMaterial = new MeshStandardMaterial({
193-
color: new Color(0xa071da),
194-
metalness: 1,
195-
roughness: 0.75,
196-
side: FrontSide,
197-
depthWrite: false // 保持原有设置
192+
const globeMaterial = new MeshPhysicalMaterial({
193+
color: new Color(0x0d0c27),
194+
transparent: true, // 启用透明
195+
transmission: 1, // 透光率
196+
thickness: 0.5, // 厚度
197+
roughness: 0.75, // 粗糙度
198+
metalness: 0, // 金属感
199+
ior: 1.5, // 折射率
200+
envMapIntensity: 1.5, // 环境贴图强度
201+
reflectivity: 0.1, // 反射率
202+
opacity: 0.55, // 不透明度
203+
side: DoubleSide, // 双面渲染
198204
})
199205

200206
globe
201207
.showGlobe(true)
202208
.globeMaterial(globeMaterial)
203209
.showAtmosphere(true)
204-
.atmosphereColor("#a071da")
210+
.atmosphereColor("#0d0c27")
205211
.atmosphereAltitude(0.25)
206212

207213
globe
@@ -211,7 +217,7 @@ const Globe3DMap = React.memo(({ wafAttackTrajectoryData }: { wafAttackTrajector
211217
.hexPolygonMargin(0.4)
212218
.hexPolygonColor((e) => {
213219
const countryCode = (e as FeatureCollection<Geometry, GeoJsonProperties>["features"][number]).properties!.ISO_A3
214-
return (countryCode === "CHN" || countryCode === "TWN") ? "rgba(255, 255, 255, 1)" : "rgba(241, 230, 255, 0.87)"
220+
return (countryCode === "CHN" || countryCode === "TWN") ? "rgba(255, 255, 255, 1)" : "rgba(241, 230, 255, 1)"
215221
})
216222

217223
// 设置 onGlobeReady 回调(只设置一次)
@@ -354,7 +360,7 @@ const Globe3DMap = React.memo(({ wafAttackTrajectoryData }: { wafAttackTrajector
354360
// 根据攻击类型分配颜色
355361
return WAF_ATTACK_TRAJECTORY_COLORS[attackTrajectory.colorIndex]
356362
})
357-
.arcAltitude((e: unknown) => (e as WAFAttackTrajectory).arcAlt)
363+
.arcAltitude((e: unknown) => Math.pow((e as WAFAttackTrajectory).arcAlt * 0.22, 1.225)) // 攻击轨迹高度(因为此处的arcAlt是地理距离, 所以需要适配四次贝塞尔曲线的高度, 距离越远需要给的补偿值越大因此使用倍率加次方计算)
358364
.arcStroke(0.3) // 攻击轨迹线条粗细
359365
.arcDashLength(0.9)
360366
.arcDashGap(4)

0 commit comments

Comments
 (0)