好好好
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
yiqiu
2025-11-22 18:10:28 +08:00
parent 51fd1035aa
commit 46fb008127

View File

@@ -65,6 +65,31 @@
{ name: "San Francisco", lat: 37.8, lng: -122.4 }
];
// 基于节点构造“飞行轨迹”连接数据startLat/startLng -> endLat/endLng
function buildArcsFromNodes(list) {
var arcs = [];
if (!Array.isArray(list) || list.length < 2) {
return arcs;
}
// 简单策略:每个节点连接到后面第 step 个节点,形成环状主干网络
var step = Math.max(1, Math.floor(list.length / 3));
list.forEach(function (src, idx) {
var dst = list[(idx + step) % list.length];
if (!dst || (dst.lat === src.lat && dst.lng === src.lng)) {
return;
}
arcs.push({
startLat: src.lat,
startLng: src.lng,
endLat: dst.lat,
endLng: dst.lng,
// 统一使用偏青色的轨迹,贴合云服务器 / CDN 的科技感
color: "#38BDF8",
});
});
return arcs;
}
// three-globe 实例使用空心陆地多边形hollow globe 风格)
var globe = new ThreeGlobe({
waitForGlobeReady: true,
@@ -79,8 +104,40 @@
scene.add(globe);
// 存放自定义“闪烁节点” mesh便于在动画循环中更新
var nodeGlows = [];
// 构造并应用“节点连接 + 飞行轨迹”效果
var arcs = buildArcsFromNodes(nodes);
if (typeof globe.arcsData === "function" && arcs.length) {
globe.arcsData(arcs);
if (typeof globe.arcColor === "function") {
globe.arcColor(function (d) {
return d.color || "#38BDF8";
});
}
if (typeof globe.arcAltitude === "function") {
globe.arcAltitude(0.2);
}
if (typeof globe.arcStroke === "function") {
globe.arcStroke(0.7);
}
// 使用虚线 + 动画时间制造“飞行”感
if (typeof globe.arcDashLength === "function") {
globe.arcDashLength(0.35);
}
if (typeof globe.arcDashGap === "function") {
globe.arcDashGap(0.8);
}
if (typeof globe.arcDashInitialGap === "function") {
globe.arcDashInitialGap(function () {
return Math.random();
});
}
if (typeof globe.arcDashAnimateTime === "function") {
globe.arcDashAnimateTime(function () {
// 4~7 秒一圈,避免所有轨迹节奏完全一致
return 4000 + Math.random() * 3000;
});
}
}
// 告诉 three-globe 当前渲染器的实际尺寸,避免默认按全窗口大小计算导致比例失真
if (typeof globe.rendererSize === "function") {
@@ -95,6 +152,15 @@
var dist = r * 3.2;
camera.position.set(0, 0.2, dist);
camera.lookAt(0, 0, 0);
// 在节点位置放置小型静态“节点点”,替代原来的绿色闪烁效果
var nodeGeom = new THREE.SphereGeometry(r * 0.02, 16, 16);
var nodeMat = new THREE.MeshBasicMaterial({
color: "#38BDF8",
transparent: true,
opacity: 0.9,
});
// 通知 three-globe 当前视角,用于部分图层的内部计算
if (typeof globe.setPointOfView === "function") {
globe.setPointOfView(camera);
@@ -102,7 +168,7 @@
// 使用 globe 的工具方法,将经纬度转换为球面上的 3D 坐标
var hasGetCoords = typeof globe.getCoords === "function";
nodes.forEach(function (n, idx) {
nodes.forEach(function (n) {
var pos;
if (hasGetCoords) {
// altitude 略高于球面,避免被多边形遮挡
@@ -119,22 +185,9 @@
};
}
var glowGeom = new THREE.SphereGeometry(r * 0.03, 16, 16);
var glowMat = new THREE.MeshBasicMaterial({
// 绿色闪烁点,和蓝色陆地形成冷暖对比
color: "#22C55E",
transparent: true,
opacity: 0.7
});
var glowMesh = new THREE.Mesh(glowGeom, glowMat);
glowMesh.position.set(pos.x, pos.y, pos.z);
globe.add(glowMesh);
nodeGlows.push({
mesh: glowMesh,
// 随机相位,让节点闪烁不同步
phase: Math.random() * Math.PI * 2 + idx
});
var nodeMesh = new THREE.Mesh(nodeGeom, nodeMat);
nodeMesh.position.set(pos.x, pos.y, pos.z);
globe.add(nodeMesh);
});
});
}
@@ -219,14 +272,6 @@
// 地球自转
globe.rotation.y += delta * 0.25;
// 节点“呼吸式”闪烁
var t = now / 1000;
nodeGlows.forEach(function (n) {
var s = 0.7 + 0.3 * Math.sin(t * 3 + n.phase);
n.mesh.scale.set(s, s, s);
n.mesh.material.opacity = 0.4 + 0.4 * Math.sin(t * 3 + n.phase);
});
renderer.render(scene, camera);
}