// ECharts世界地图背景版 - 无飞行路线 class BackgroundWorldMap { constructor() { this.chart = null; this.mapData = null; this.visitedCountries = [ '中国', '日本', '韩国', '泰国', '新加坡', '马来西亚', '印度尼西亚', '菲律宾', '越南', '印度', '阿联酋', '土耳其', '埃及', '南非', '美国', '加拿大', '墨西哥', '巴西', '阿根廷', '英国', '法国', '德国', '意大利', '西班牙', '荷兰', '比利时', '瑞士', '奥地利', '捷克', '波兰', '俄罗斯', '澳大利亚', '新西兰', '冰岛', '挪威', '瑞典', '芬兰', '丹麦', '葡萄牙', '希腊', '摩洛哥', '肯尼亚' ]; this.initializeMap(); } async initializeMap() { const container = document.getElementById('hero-map-background'); if (!container) { console.error('地图容器不存在'); return; } if (typeof echarts === 'undefined') { console.error('ECharts库未加载'); return; } try { // 加载地图数据 const response = await fetch('worldZH.json'); if (!response.ok) { throw new Error('地图数据加载失败'); } this.mapData = await response.json(); // 修改地图数据,确保所有区域都有统一的样式 if (this.mapData.features) { this.mapData.features.forEach(feature => { if (!feature.properties) { feature.properties = {}; } // 给所有地区设置统一的属性值 feature.properties.value = 50; // 统一的值,配合visualMap使用 }); } echarts.registerMap('world', this.mapData); // 初始化图表 this.initChart(container); } catch (error) { console.error('地图初始化失败:', error); } } initChart(container) { // 检查容器是否已经有图表实例 const existingInstance = echarts.getInstanceByDom(container); if (existingInstance) { console.log('容器已有图表实例,先销毁'); existingInstance.dispose(); } // 确保容器有正确的尺寸 const rect = container.getBoundingClientRect(); // 创建ECharts实例,明确指定尺寸 this.chart = echarts.init(container, null, { renderer: 'canvas', width: rect.width || window.innerWidth, height: rect.height || window.innerHeight }); // 立即调整大小以适应容器 setTimeout(() => { this.chart.resize(); // 重新设置中心点以确保居中 this.adjustMapCenter(); }, 100); // 所有国家现在都使用统一的绿色样式 // 主要城市点 - 简化版本 const cityPoints = [ { name: '北京', value: [116.4074, 39.9042, 100] }, { name: '东京', value: [139.6917, 35.6895, 95] }, { name: '巴黎', value: [2.3522, 48.8566, 92] }, { name: '纽约', value: [-74.0060, 40.7128, 95] }, { name: '伦敦', value: [-0.1276, 51.5074, 90] }, { name: '悉尼', value: [151.2093, -33.8688, 90] }, { name: '迪拜', value: [55.2708, 25.2048, 85] }, { name: '新加坡', value: [103.8198, 1.3521, 88] }, { name: '巴厘岛', value: [115.1889, -8.4095, 100] }, // 当前位置 { name: '罗马', value: [12.4964, 41.9028, 94] }, { name: '马德里', value: [-3.7038, 40.4168, 86] }, { name: '柏林', value: [13.4050, 52.5200, 88] }, { name: '莫斯科', value: [37.6173, 55.7558, 76] }, { name: '开罗', value: [31.2357, 30.0444, 72] }, { name: '里约热内卢', value: [-43.1729, -22.9068, 82] } ]; // 配置项 - 简洁的背景风格 const option = { backgroundColor: 'transparent', tooltip: { trigger: 'item', backgroundColor: 'rgba(10, 14, 39, 0.95)', borderColor: 'rgba(0, 180, 216, 0.5)', borderWidth: 1, textStyle: { color: '#90e0ef', fontSize: 12 }, formatter: function(params) { if (params.seriesType === 'scatter' || params.seriesType === 'effectScatter') { return `
${params.name}
访问指数:${params.value[2] || 100}%
`; } else if (params.componentType === 'geo') { return `
${params.name}
点击查看详情
`; } return params.name; } }, geo: { map: 'world', roam: false, // 禁用缩放和拖拽 center: [0, 0], // 世界地图标准中心 zoom: 1.2, // 适度放大 silent: false, // 允许交互 left: 'center', // 水平居中 top: 'center', // 垂直居中 aspectScale: 0.75, // 调整宽高比以补偿投影变形 itemStyle: { normal: { areaColor: 'rgba(82, 183, 136, 0.35)', // 统一绿色高亮 borderColor: 'rgba(82, 183, 136, 0.3)', borderWidth: 0.8 } }, emphasis: { disabled: false, itemStyle: { areaColor: 'rgba(82, 183, 136, 0.5)', borderColor: 'rgba(82, 183, 136, 0.8)', borderWidth: 2, shadowBlur: 10, shadowColor: 'rgba(82, 183, 136, 0.5)' }, label: { show: true, color: '#52b788', fontSize: 14, fontWeight: 'bold' } }, regions: [] // 清空所有特殊区域配置 }, series: [ // 城市散点 - 更简洁 { name: '城市', type: 'scatter', coordinateSystem: 'geo', data: cityPoints, symbolSize: function(val) { return Math.max(val[2] / 12, 4); // 更小的点 }, itemStyle: { color: function(params) { const value = params.value[2]; // 使用更柔和的颜色 if (value >= 90) return 'rgba(255, 107, 53, 0.6)'; if (value >= 80) return 'rgba(244, 162, 97, 0.6)'; return 'rgba(0, 180, 216, 0.6)'; }, shadowBlur: 5, shadowColor: 'rgba(0, 180, 216, 0.3)' }, emphasis: { itemStyle: { shadowBlur: 10, shadowColor: 'rgba(255, 107, 53, 0.5)' }, label: { show: true, formatter: '{b}', position: 'top', color: '#fff', fontSize: 12 } }, silent: false // 允许交互 }, // 当前位置脉冲效果 { name: '当前位置', type: 'effectScatter', coordinateSystem: 'geo', data: [{ name: '巴厘岛', value: [115.1889, -8.4095] }], symbolSize: 15, rippleEffect: { period: 4, scale: 2.5, brushType: 'fill' }, itemStyle: { color: 'rgba(255, 107, 53, 0.7)', shadowBlur: 10, shadowColor: 'rgba(255, 107, 53, 0.5)' }, silent: true // 不响应鼠标事件 } ] }; // 应用配置 this.chart.setOption(option); // 响应式 window.addEventListener('resize', () => { if (this.chart) { this.chart.resize(); } }); // 美化的点击交互 this.chart.on('click', 'series.scatter', (params) => { this.showCityInfo(params); }); // 点击地图区域显示国家信息 this.chart.on('click', 'geo', (params) => { if (params.name) { this.showCountryInfo(params); } }); } showCityInfo(params) { // 移除已存在的弹窗 const existingModal = document.querySelector('.map-info-modal'); if (existingModal) { existingModal.remove(); } const modal = document.createElement('div'); modal.className = 'map-info-modal'; modal.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: linear-gradient(135deg, rgba(10, 14, 39, 0.98) 0%, rgba(38, 70, 83, 0.95) 100%); border: 2px solid rgba(0, 180, 216, 0.5); border-radius: 20px; padding: 30px; z-index: 10000; color: white; min-width: 320px; max-width: 400px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5), 0 0 100px rgba(0, 180, 216, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); animation: modalFadeIn 0.3s ease; `; const value = params.value[2] || 0; const cityData = this.getCityData(params.name); modal.innerHTML = `

${params.name}

${cityData.emoji}

${cityData.country}

🌟 访问指数

${value}%

${cityData.description}

`; document.body.appendChild(modal); // 点击背景关闭 setTimeout(() => { modal.addEventListener('click', (e) => { if (e.target === modal) { modal.remove(); } }); }, 100); } showCountryInfo(params) { // 移除已存在的弹窗 const existingModal = document.querySelector('.map-info-modal'); if (existingModal) { existingModal.remove(); } const modal = document.createElement('div'); modal.className = 'map-info-modal'; modal.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: linear-gradient(135deg, rgba(10, 14, 39, 0.98) 0%, rgba(38, 70, 83, 0.95) 100%); border: 2px solid rgba(82, 183, 136, 0.5); border-radius: 20px; padding: 30px; z-index: 10000; color: white; min-width: 320px; max-width: 400px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5), 0 0 100px rgba(82, 183, 136, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); animation: modalFadeIn 0.3s ease; `; const countryData = this.getCountryData(params.name); const isVisited = this.visitedCountries.includes(params.name); modal.innerHTML = `

${params.name}

${countryData.flag}
${isVisited ? '✓ 已访问' : '◯ 未访问'}
${isVisited ? `

访问记录

${countryData.visitInfo}

` : ''}

${countryData.description}

`; document.body.appendChild(modal); // 点击背景关闭 setTimeout(() => { modal.addEventListener('click', (e) => { if (e.target === modal) { modal.remove(); } }); }, 100); } getCityData(cityName) { const cityDatabase = { '北京': { emoji: '🏛️', country: '中国', description: '千年古都,现代化国际大都市' }, '东京': { emoji: '🗼', country: '日本', description: '繁华都市,传统与现代的完美融合' }, '巴黎': { emoji: '🗼', country: '法国', description: '浪漫之都,艺术与时尚的天堂' }, '纽约': { emoji: '🗽', country: '美国', description: '世界之都,梦想开始的地方' }, '伦敦': { emoji: '🎡', country: '英国', description: '雾都传奇,历史与现代交织' }, '悉尼': { emoji: '🌉', country: '澳大利亚', description: '海港城市,阳光与海滩的乐园' }, '迪拜': { emoji: '🏙️', country: '阿联酋', description: '沙漠奇迹,奢华与创新的象征' }, '新加坡': { emoji: '🦁', country: '新加坡', description: '花园城市,多元文化的交汇点' }, '巴厘岛': { emoji: '🏝️', country: '印度尼西亚', description: '诸神之岛,心灵净化的圣地' }, '罗马': { emoji: '🏛️', country: '意大利', description: '永恒之城,历史在每个角落' }, '马德里': { emoji: '🎭', country: '西班牙', description: '热情之都,弗拉明戈的故乡' }, '柏林': { emoji: '🏰', country: '德国', description: '历史见证,艺术与创意的中心' }, '莫斯科': { emoji: '🏰', country: '俄罗斯', description: '红场传说,东西方文化的桥梁' }, '开罗': { emoji: '🔺', country: '埃及', description: '金字塔之城,古文明的守护者' }, '里约热内卢': { emoji: '🏖️', country: '巴西', description: '狂欢之都,桑巴与海滩的天堂' } }; return cityDatabase[cityName] || { emoji: '📍', country: '未知', description: '等待探索的神秘之地' }; } getCountryData(countryName) { const countryDatabase = { '中国': { flag: '🇨🇳', visitInfo: '2次访问 · 30天', description: '五千年文明,山河壮丽,美食天堂' }, '日本': { flag: '🇯🇵', visitInfo: '3次访问 · 21天', description: '樱花之国,匠人精神,科技与传统并存' }, '美国': { flag: '🇺🇸', visitInfo: '2次访问 · 15天', description: '自由之地,多元文化,创新的摇篮' }, '法国': { flag: '🇫🇷', visitInfo: '1次访问 · 10天', description: '浪漫国度,美食美酒,艺术殿堂' }, '英国': { flag: '🇬🇧', visitInfo: '1次访问 · 7天', description: '绅士之国,皇家传统,现代金融中心' }, '澳大利亚': { flag: '🇦🇺', visitInfo: '1次访问 · 14天', description: '袋鼠之国,自然奇观,冲浪天堂' }, '新加坡': { flag: '🇸🇬', visitInfo: '2次访问 · 5天', description: '狮城,花园城市,美食汇聚' }, '印度尼西亚': { flag: '🇮🇩', visitInfo: '1次访问 · 10天', description: '千岛之国,热带风情,文化多样' }, '意大利': { flag: '🇮🇹', visitInfo: '1次访问 · 12天', description: '艺术之国,美食故乡,历史瑰宝' }, '西班牙': { flag: '🇪🇸', visitInfo: '1次访问 · 8天', description: '热情国度,弗拉明戈,阳光海岸' }, '德国': { flag: '🇩🇪', visitInfo: '1次访问 · 6天', description: '严谨之国,啤酒文化,工业强国' }, '俄罗斯': { flag: '🇷🇺', visitInfo: '1次访问 · 9天', description: '战斗民族,文学艺术,广袤国土' }, '埃及': { flag: '🇪🇬', visitInfo: '1次访问 · 7天', description: '法老之国,金字塔,尼罗河文明' }, '巴西': { flag: '🇧🇷', visitInfo: '1次访问 · 10天', description: '桑巴王国,亚马逊雨林,足球圣地' } }; return countryDatabase[countryName] || { flag: '🏳️', visitInfo: '', description: '尚未探索的神秘土地,等待下一次冒险' }; } adjustMapCenter() { // 动态调整地图中心以适应容器 const containerWidth = this.chart.getWidth(); const containerHeight = this.chart.getHeight(); const aspectRatio = containerWidth / containerHeight; // 根据容器宽高比调整中心点 let centerX = -100; let centerY = 20; // 如果容器更宽,稍微向左偏移 if (aspectRatio > 1.5) { centerX = 160; } // 更新地图中心,保持原有的颜色配置 this.chart.setOption({ geo: { center: [centerX, centerY], itemStyle: { normal: { areaColor: 'rgba(82, 183, 136, 0.35)', // 保持统一绿色 borderColor: 'rgba(82, 183, 136, 0.3)', borderWidth: 0.8 } } } }); } destroy() { if (this.chart) { this.chart.dispose(); this.chart = null; } } } // 初始化背景地图 - 确保只创建一次 let mapInitialized = false; function initializeMap() { // 防止重复初始化 if (mapInitialized || window.backgroundMap) { console.log('地图已经初始化,跳过'); return; } const container = document.getElementById('hero-map-background'); if (!container) { console.warn('地图容器不存在'); return; } // 清空容器内容 container.innerHTML = ''; // 标记为已初始化 mapInitialized = true; // 创建地图实例 try { window.backgroundMap = new BackgroundWorldMap(); console.log('地图初始化成功'); } catch (error) { console.error('地图初始化失败:', error); mapInitialized = false; } } // DOM加载完成后初始化 document.addEventListener('DOMContentLoaded', () => { // 延迟执行以确保所有资源加载完成 setTimeout(initializeMap, 200); });