diff --git a/index.html b/index.html
index 5cc32bf..7f69caf 100644
--- a/index.html
+++ b/index.html
@@ -5,11 +5,10 @@
-
+
-
+
+
diff --git a/js/globe.js b/js/globe.js
index 3ef3989..4d58295 100644
--- a/js/globe.js
+++ b/js/globe.js
@@ -1,5 +1,5 @@
-// 3D 地球效果(首页 banner 右侧)
-// 依赖:Three.js(全局 THREE 对象),脚本路径建议:/web/BlackFruit-web/vender/three/three.min.js
+// 3D 地球效果(首页 banner 右侧)基于 three-globe
+// 依赖:全局 THREE 和 ThreeGlobe(在 index.html 中通过 CDN 引入)
(function () {
function initGlobe() {
@@ -9,114 +9,110 @@
return;
}
if (typeof THREE === "undefined") {
- // Three.js 未加载时直接跳过,不影响其它功能
- console.warn("[Globe] THREE is undefined, please ensure three.min.js is loaded");
+ console.warn(
+ "[Globe] THREE is undefined, please ensure three.min.js is loaded"
+ );
+ return;
+ }
+ if (typeof ThreeGlobe === "undefined") {
+ console.warn(
+ "[Globe] ThreeGlobe is undefined, please ensure three-globe.min.js is loaded"
+ );
return;
}
var width = container.clientWidth || 400;
var height = container.clientHeight || 400;
+ // 基础 Three.js 场景
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
- var radius = 1.2;
- camera.position.set(0, 0, radius * 3.2);
+ // 稍微偏右俯视一点
+ camera.position.set(0, 0.4, 4.0);
camera.lookAt(0, 0, 0);
var renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
renderer.setSize(width, height);
- renderer.setClearColor(0x000000, 0); // 透明背景,融入页面
+ renderer.setClearColor(0x000000, 0); // 透明背景
container.appendChild(renderer.domElement);
- // 光照:柔和的环境光 + 方向光
- scene.add(new THREE.AmbientLight(0xffffff, 0.5));
+ // 柔和光照
+ var ambient = new THREE.AmbientLight(0xffffff, 0.65);
+ scene.add(ambient);
var dirLight = new THREE.DirectionalLight(0xffffff, 0.9);
dirLight.position.set(5, 3, 5);
scene.add(dirLight);
- var globeGroup = new THREE.Group();
- scene.add(globeGroup);
-
- // 地球球体
- var earthGeometry = new THREE.SphereGeometry(radius, 64, 64);
-
- // 纯色高光材质,若后续有贴图可替换为 MeshPhongMaterial + map
- var earthMaterial = new THREE.MeshPhongMaterial({
- color: 0x163a5f,
- emissive: 0x061727,
- shininess: 35,
- specular: 0x3aaefc,
- });
-
- var earthMesh = new THREE.Mesh(earthGeometry, earthMaterial);
- globeGroup.add(earthMesh);
-
- // 大气层发光效果
- var atmosphereGeometry = new THREE.SphereGeometry(radius * 1.06, 64, 64);
- var atmosphereMaterial = new THREE.MeshBasicMaterial({
- color: 0x2b9fff,
- transparent: true,
- opacity: 0.25,
- side: THREE.BackSide,
- });
- var atmosphereMesh = new THREE.Mesh(
- atmosphereGeometry,
- atmosphereMaterial
- );
- globeGroup.add(atmosphereMesh);
-
- // 将经纬度转换为球面坐标
- function latLngToVector3(lat, lng, r) {
- var phi = (90 - lat) * (Math.PI / 180);
- var theta = (lng + 180) * (Math.PI / 180);
- var x = -r * Math.sin(phi) * Math.cos(theta);
- var z = r * Math.sin(phi) * Math.sin(theta);
- var y = r * Math.cos(phi);
- return new THREE.Vector3(x, y, z);
- }
-
- // 一些示例节点(可以根据业务改为真实机房经纬度)
- var nodeConfigs = [
- { lat: 39.9, lng: 116.4 }, // 北京
- { lat: 31.2, lng: 121.5 }, // 上海
- { lat: 22.5, lng: 114.1 }, // 香港
- { lat: 1.3, lng: 103.8 }, // 新加坡
- { lat: 37.8, lng: -122.4 }, // 旧金山
- { lat: 52.5, lng: 13.4 }, // 柏林
- { lat: 35.7, lng: 139.7 }, // 东京
+ // 示例节点数据(可后续替换为真实机房经纬度)
+ 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: "Singapore", lat: 1.3, lng: 103.8 },
+ { name: "San Francisco", lat: 37.8, lng: -122.4 },
+ { name: "Berlin", lat: 52.5, lng: 13.4 },
+ { name: "Tokyo", lat: 35.7, lng: 139.7 },
];
- var nodeGroup = new THREE.Group();
- globeGroup.add(nodeGroup);
-
- var nodeMaterial = new THREE.MeshBasicMaterial({
- color: 0x5ad8ff,
- });
-
- var nodes = [];
- var nodeRadius = radius * 0.03;
- nodeConfigs.forEach(function (cfg, index) {
- var pos = latLngToVector3(cfg.lat, cfg.lng, radius * 1.02);
- var geom = new THREE.SphereGeometry(nodeRadius, 16, 16);
- var mesh = new THREE.Mesh(geom, nodeMaterial);
- mesh.position.copy(pos);
- nodeGroup.add(mesh);
-
- nodes.push({
- mesh: mesh,
- baseScale: 1,
- phase: Math.random() * Math.PI * 2 + index,
+ // 示例 arcs:从北京发出到其他节点
+ var arcs = nodes
+ .filter(function (n) {
+ return n.name !== "Beijing";
+ })
+ .map(function (n) {
+ return {
+ startLat: 39.9,
+ startLng: 116.4,
+ endLat: n.lat,
+ endLng: n.lng,
+ };
});
- });
- // 通过 Points 实现星空点阵背景
+ // three-globe 实例
+ var globe = new ThreeGlobe({
+ waitForGlobeReady: true,
+ animateIn: true,
+ })
+ // 夜间地球 + 地形凹凸贴图(使用 three-globe 示例贴图)
+ .globeImageUrl(
+ "https://unpkg.com/three-globe/example/img/earth-night.jpg"
+ )
+ .bumpImageUrl(
+ "https://unpkg.com/three-globe/example/img/earth-topology.png"
+ )
+ .showAtmosphere(true)
+ .atmosphereColor("#2b9fff")
+ .atmosphereAltitude(0.18)
+ .showGraticules(false)
+ // 节点柱状体
+ .pointsData(nodes)
+ .pointColor(function () {
+ return "#5ad8ff";
+ })
+ .pointAltitude(0.06)
+ .pointRadius(0.32)
+ .pointsTransitionDuration(1000)
+ // 弧线
+ .arcsData(arcs)
+ .arcColor(function () {
+ return ["#5ad8ff", "#ffffff"];
+ })
+ .arcAltitude(0.35)
+ .arcStroke(0.45)
+ .arcDashLength(0.6)
+ .arcDashGap(0.25)
+ .arcDashAnimateTime(2600);
+
+ scene.add(globe);
+
+ // 星辰背景(简单加一点点空间感)
var starGeometry = new THREE.BufferGeometry();
var starCount = 600;
var starPositions = new Float32Array(starCount * 3);
for (var i = 0; i < starCount; i++) {
- var sr = radius * 4 + Math.random() * radius * 2;
+ var sr = 10 + Math.random() * 5;
var theta = Math.random() * Math.PI * 2;
var phi = Math.acos(2 * Math.random() - 1);
var sx = sr * Math.sin(phi) * Math.cos(theta);
@@ -132,9 +128,9 @@
);
var starMaterial = new THREE.PointsMaterial({
color: 0x3f76ff,
- size: 0.02,
+ size: 0.08,
transparent: true,
- opacity: 0.8,
+ opacity: 0.7,
});
var stars = new THREE.Points(starGeometry, starMaterial);
scene.add(stars);
@@ -152,7 +148,6 @@
// 动画循环
var lastTime = performance.now();
-
function animate() {
requestAnimationFrame(animate);
@@ -160,18 +155,10 @@
var delta = (now - lastTime) / 1000;
lastTime = now;
- // 地球缓慢自转
- globeGroup.rotation.y += delta * 0.25;
-
- // 星辰慢速旋转,增强空间感
- stars.rotation.y -= delta * 0.05;
-
- // 节点呼吸效果
- var t = now / 1000;
- nodes.forEach(function (n) {
- var s = n.baseScale * (1 + 0.6 * Math.sin(t * 2.5 + n.phase));
- n.mesh.scale.set(s, s, s);
- });
+ // 地球自转
+ globe.rotation.y += delta * 0.25;
+ // 星空轻微旋转
+ stars.rotation.y -= delta * 0.03;
renderer.render(scene, camera);
}