
先看一下效果它能做什么3D 地球仪48 支参赛队标注在地球上按小组着色点击球队查看积分和战绩今日赛事双方用金色弧线连接点击弧线直接跳到比赛详情实时赛程覆盖最近 ±4 天比赛点击任意场次展开完整时间线进球 / 换人 / 黄红牌12 小组积分榜每 30 分钟自动更新完整积分 / 净胜球 / 近期状态赛事预测结合 DraftKings 赔率和积分数据生成胜负概率带详细分析AI 助手内置 Claude 聊天用你自己的 Anthropic API KeyKey 只存本地浏览器中英文双语一键切换。技术架构整个项目没有后端没有构建工具没有 npm install。浏览器 ─── 读取 data/*.json ──── GitHub Pages静态文件 ↑ GitHub Actions每 30 分钟 │ sports-skills CLI ESPN API无需 Key核心技术选型层选择原因3D 渲染Three.js v0.165CDN importmap无需打包浏览器直接加载 ES Module数据管道GitHub Actions Python免费、定时、可写仓库数据源sports-skillsESPN API无需注册覆盖世界杯全量数据AIAnthropic Claude API浏览器直连用户自带 Key部署GitHub Pages免费静态托管为什么不用框架纯 HTML ES Modules加载速度极快也方便任何人 fork 后直接改。Three.js 通过 importmap 从 CDN 加载页面打开就能用没有任何构建步骤。数据更新机制# .github/workflows/fetch-data.yml on: schedule: - cron: */30 * * * * # 每 30 分钟Action 跑 Python 脚本调用 sports-skills CLI 抓 ESPN 数据写入data/*.jsoncommit 后触发 Pages 重新部署。比赛期间数据延迟不超过 30 分钟。3D 地球仪实现要点地球仪基于 Three.js核心是用经纬度坐标把球队标注到球面function latLonToVec(lat, lon, r 1.02) { const phi (90 - lat) * Math.PI / 180; const theta (lon 180) * Math.PI / 180; return new THREE.Vector3( Math.sin(phi) * Math.cos(theta) * r, Math.cos(phi) * r, Math.sin(phi) * Math.sin(theta) * r ); }今日赛事连线用二次贝塞尔曲线生成弧线拱起高度根据两点中点距球心的距离自动计算视觉上有自然的弧度感function makeArc(p1, p2, color) { const mid p1.clone().add(p2).multiplyScalar(0.5); const lift 1 0.35 * (1 - mid.length()); mid.normalize().multiplyScalar(lift 0.2); // 二次贝塞尔采样 const pts []; for (let t 0; t 1; t 0.02) { pts.push( p1.clone().multiplyScalar((1-t)*(1-t)) .add(mid.clone().multiplyScalar(2*t*(1-t))) .add(p2.clone().multiplyScalar(t*t)) ); } return new THREE.Line(new THREE.BufferGeometry().setFromPoints(pts), ...); }AI 助手的实现细节