功能特性: - 3D地球动画与中国地图可视化 - 省份/城市/企业搜索功能 - 308家企业数据展示 - 响应式设计(PC端和移动端) - 企业详情页面与业务板块展示 - 官网新闻轮播图 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
128 lines
3.9 KiB
JavaScript
128 lines
3.9 KiB
JavaScript
/* ===================================
|
||
地球模型 - 包含地球、云层、大气层
|
||
=================================== */
|
||
|
||
import { CONFIG } from '../config.js';
|
||
|
||
export class EarthModel {
|
||
constructor(scene) {
|
||
this.scene = scene;
|
||
this.earthGroup = new THREE.Group();
|
||
this.earth = null;
|
||
this.clouds = null;
|
||
this.atmosphere = null;
|
||
this.loader = new THREE.TextureLoader();
|
||
|
||
this.init();
|
||
}
|
||
|
||
// 初始化地球模型
|
||
init() {
|
||
const radius = CONFIG.scene.earth.radius;
|
||
const segments = CONFIG.scene.earth.segments;
|
||
|
||
// 创建地球
|
||
this.earth = new THREE.Mesh(
|
||
new THREE.SphereGeometry(radius, segments, segments),
|
||
new THREE.MeshPhongMaterial({
|
||
map: this.loader.load(CONFIG.textures.earthMap),
|
||
specularMap: this.loader.load(CONFIG.textures.earthSpecular),
|
||
normalMap: this.loader.load(CONFIG.textures.earthNormal),
|
||
specular: new THREE.Color(0x111111),
|
||
shininess: 5
|
||
})
|
||
);
|
||
this.earthGroup.add(this.earth);
|
||
|
||
// 创建云层
|
||
this.clouds = new THREE.Mesh(
|
||
new THREE.SphereGeometry(CONFIG.scene.earth.cloudRadius, segments, segments),
|
||
new THREE.MeshLambertMaterial({
|
||
map: this.loader.load(CONFIG.textures.earthClouds),
|
||
transparent: true,
|
||
opacity: 0.9,
|
||
blending: THREE.AdditiveBlending
|
||
})
|
||
);
|
||
this.earthGroup.add(this.clouds);
|
||
|
||
// 创建大气光晕
|
||
this.atmosphere = new THREE.Mesh(
|
||
new THREE.SphereGeometry(CONFIG.scene.earth.atmosphereRadius, segments, segments),
|
||
new THREE.ShaderMaterial({
|
||
vertexShader: `
|
||
varying vec3 vNormal;
|
||
void main() {
|
||
vNormal = normalize(normalMatrix * normal);
|
||
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
||
}
|
||
`,
|
||
fragmentShader: `
|
||
varying vec3 vNormal;
|
||
void main() {
|
||
float intensity = pow(0.55 - dot(vNormal, vec3(0, 0, 1.0)), 4.5);
|
||
gl_FragColor = vec4(0.0, 0.6, 1.0, 1.0) * intensity;
|
||
}
|
||
`,
|
||
blending: THREE.AdditiveBlending,
|
||
side: THREE.BackSide,
|
||
transparent: true
|
||
})
|
||
);
|
||
|
||
// 大气层独立添加到场景(不在earthGroup中,避免被旋转)
|
||
this.scene.add(this.atmosphere);
|
||
this.scene.add(this.earthGroup);
|
||
}
|
||
|
||
// 自动旋转地球和云层
|
||
rotate() {
|
||
if (this.earthGroup) {
|
||
this.earthGroup.rotation.y += 0.0008;
|
||
}
|
||
if (this.clouds) {
|
||
this.clouds.rotation.y += 0.0010;
|
||
}
|
||
}
|
||
|
||
// 获取可交互对象(用于射线检测)
|
||
getInteractiveObjects() {
|
||
return [this.earth, this.clouds];
|
||
}
|
||
|
||
// 获取地球组(用于转场旋转)
|
||
getGroup() {
|
||
return this.earthGroup;
|
||
}
|
||
|
||
// 获取大气层(用于悬停效果)
|
||
getAtmosphere() {
|
||
return this.atmosphere;
|
||
}
|
||
|
||
// 获取云层(用于转场淡出)
|
||
getClouds() {
|
||
return this.clouds;
|
||
}
|
||
|
||
// 销毁
|
||
dispose() {
|
||
if (this.earth) {
|
||
this.earth.geometry.dispose();
|
||
this.earth.material.dispose();
|
||
}
|
||
if (this.clouds) {
|
||
this.clouds.geometry.dispose();
|
||
this.clouds.material.dispose();
|
||
}
|
||
if (this.atmosphere) {
|
||
this.atmosphere.geometry.dispose();
|
||
this.atmosphere.material.dispose();
|
||
this.scene.remove(this.atmosphere);
|
||
}
|
||
if (this.earthGroup) {
|
||
this.scene.remove(this.earthGroup);
|
||
}
|
||
}
|
||
}
|