diff --git a/js/globe.js b/js/globe.js index b2139a1..7be1e34 100644 --- a/js/globe.js +++ b/js/globe.js @@ -45,18 +45,27 @@ dirLight.position.set(5, 3, 5); scene.add(dirLight); - // 节点数据示例(可替换为真实机房经纬度) + // 节点数据示例(可替换为真实机房经纬度,至少 15 个) var nodes = [ { name: "Beijing", lat: 39.9, lng: 116.4 }, { name: "Shanghai", lat: 31.2, lng: 121.5 }, - { name: "Hong Kong", lat: 22.5, lng: 114.1 }, + { name: "Guangzhou", lat: 23.1, lng: 113.3 }, + { name: "Shenzhen", lat: 22.5, lng: 114.1 }, + { name: "Hong Kong", lat: 22.3, lng: 114.2 }, { name: "Singapore", lat: 1.3, lng: 103.8 }, - { name: "San Francisco", lat: 37.8, lng: -122.4 }, { name: "Tokyo", lat: 35.7, lng: 139.7 }, + { name: "Osaka", lat: 34.7, lng: 135.5 }, + { name: "Seoul", lat: 37.5, lng: 126.9 }, + { name: "Sydney", lat: -33.9, lng: 151.2 }, + { name: "Mumbai", lat: 19.0, lng: 72.8 }, { name: "Frankfurt", lat: 50.1, lng: 8.7 }, + { name: "London", lat: 51.5, lng: -0.1 }, + { name: "Paris", lat: 48.9, lng: 2.4 }, + { name: "New York", lat: 40.7, lng: -74.0 }, + { name: "San Francisco", lat: 37.8, lng: -122.4 } ]; - // three-globe 实例:使用空心陆地多边形(hollow globe 风格)+ 节点亮点 + // three-globe 实例:使用空心陆地多边形(hollow globe 风格) var globe = new ThreeGlobe({ waitForGlobeReady: true, animateIn: true, @@ -66,22 +75,13 @@ .showAtmosphere(false) .atmosphereColor("#2b9fff") .atmosphereAltitude(0.18) - .showGraticules(false) - // 节点亮点:使用 points 层模拟“闪亮节点” - .pointsData(nodes) - .pointColor(function () { - // 使用纯白色小亮点,与蓝色陆地形成明显对比 - return "#FFFFFF"; - }) - // 提高高度,确保彻底浮在陆地轮廓之上 - .pointAltitude(0.15) - // 增大节点半径,让亮点在首页视角下清晰可见 - .pointRadius(0.6) - .pointResolution(16) - .pointsTransitionDuration(0); + .showGraticules(false); scene.add(globe); + // 存放自定义“闪烁节点” mesh,便于在动画循环中更新 + var nodeGlows = []; + // 告诉 three-globe 当前渲染器的实际尺寸,避免默认按全窗口大小计算导致比例失真 if (typeof globe.rendererSize === "function") { globe.rendererSize(new THREE.Vector2(width, height)); @@ -99,6 +99,42 @@ if (typeof globe.setPointOfView === "function") { globe.setPointOfView(camera); } + + // 使用 globe 的工具方法,将经纬度转换为球面上的 3D 坐标 + var hasGetCoords = typeof globe.getCoords === "function"; + nodes.forEach(function (n, idx) { + var pos; + if (hasGetCoords) { + // altitude 略高于球面,避免被多边形遮挡 + pos = globe.getCoords(n.lat, n.lng, 0.02); + } else { + // 兼容降级:简单根据半径和经纬度计算 + var phi = (90 - n.lat) * (Math.PI / 180); + var theta = (n.lng + 180) * (Math.PI / 180); + var rr = r * 1.02; + pos = { + x: -rr * Math.sin(phi) * Math.cos(theta), + z: rr * Math.sin(phi) * Math.sin(theta), + y: rr * Math.cos(phi) + }; + } + + var glowGeom = new THREE.SphereGeometry(r * 0.03, 16, 16); + var glowMat = new THREE.MeshBasicMaterial({ + color: 0xffffff, + 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 + }); + }); }); } @@ -182,6 +218,14 @@ // 地球自转 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); }