원클릭으로
globe-gl
Globe.GL 3D 地球視覺化指南。當需要建立互動式 3D 地球、國家熱力圖、點擊導航、或整合 Astro 時使用。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Globe.GL 3D 地球視覺化指南。當需要建立互動式 3D 地球、國家熱力圖、點擊導航、或整合 Astro 時使用。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Zod v4 schema validation 最佳實踐指南。當需要定義 schema、驗證/解析 JSON 資料、type inference、或處理 unknown data 時使用。
Svelte 5 + Astro 整合最佳實踐指南。當需要建立 Svelte 元件、使用 runes API、整合 Astro islands、或用 Testing Library 測試 Svelte 元件時使用。
GitHub GraphQL API 最佳實踐指南。當需要使用 GraphQL 查詢使用者資料、處理 cursor pagination、計算 rate limit、或除錯 GraphQL errors 時使用。
gayanvoice/top-github-users 架構參考指南。當需要了解 GitHub 使用者排行榜的資料抓取管線、國家設定、排行計算邏輯、已知問題、或社群需求時使用。
Commander.js v14 CLI 框架最佳實踐。當需要建立 CLI 工具、解析命令列參數、設計 subcommands 時使用。
GitHub Actions CI/CD 最佳實踐指南。當需要設定 workflow、cron 排程、GitHub Pages 部署、使用 Octokit API、或處理 rate limiting 時使用。
| name | globe-gl |
| description | Globe.GL 3D 地球視覺化指南。當需要建立互動式 3D 地球、國家熱力圖、點擊導航、或整合 Astro 時使用。 |
npm install globe.gl
TypeScript types 已內建,不需額外安裝。
在 Astro component 的 <script> 中直接使用(client-side module):
<div id="globe-container" class="w-full h-[600px]"></div>
<script>
import Globe from "globe.gl";
// ...
</script>
import Globe from "globe.gl";
import * as THREE from "three";
const container = document.getElementById("globe-container")!;
const world = new Globe(container, {
rendererConfig: { antialias: true, alpha: true },
animateIn: true,
})
.backgroundColor("rgba(0,0,0,0)")
.showAtmosphere(true)
.atmosphereColor("#3a228a")
.atmosphereAltitude(0.25)
.globeImageUrl("//cdn.jsdelivr.net/npm/three-globe/example/img/earth-night.jpg")
.bumpImageUrl("//cdn.jsdelivr.net/npm/three-globe/example/img/earth-topology.png");
// Dark material
const mat = world.globeMaterial() as THREE.MeshPhongMaterial;
mat.color = new THREE.Color("#1a1a2e");
mat.emissive = new THREE.Color("#090920");
mat.emissiveIntensity = 0.1;
mat.shininess = 5;
// GeoJSON 來源(110m 解析度,較小)
const res = await fetch("/data/countries.geojson");
const countries = await res.json();
world
.polygonsData(countries.features.filter(f => f.properties.ISO_A2 !== "AQ"))
.polygonAltitude(0.01)
.polygonCapColor(d => getCountryColor(d))
.polygonSideColor(() => "rgba(100, 100, 200, 0.15)")
.polygonStrokeColor(() => "#44ffaa33")
.polygonLabel(d => `<div>...</div>`)
.onPolygonClick((polygon) => {
const code = polygon.properties.ISO_A2.toLowerCase();
window.location.href = `/${countryCodeMap[code]}/`;
})
.onPolygonHover((hoverD) => {
container.style.cursor = hoverD ? "pointer" : "default";
world.polygonAltitude(d => d === hoverD ? 0.04 : 0.01);
});
const controls = world.controls();
controls.autoRotate = true;
controls.autoRotateSpeed = 0.4;
controls.minDistance = 120;
controls.maxDistance = 500;
// 停止旋轉 on interaction,idle 5s 後恢復
container.addEventListener("mousedown", () => controls.autoRotate = false);
container.addEventListener("mouseup", () => {
setTimeout(() => controls.autoRotate = true, 5000);
});
// Fly to country
world.pointOfView({ lat: 25.0, lng: 121.5, altitude: 1.5 }, 1000);
function handleResize() {
world.width(container.clientWidth).height(container.clientHeight);
}
window.addEventListener("resize", handleResize);
handleResize();
// Pause when off-screen
const observer = new IntersectionObserver(([entry]) => {
entry.isIntersecting ? world.resumeAnimation() : world.pauseAnimation();
}, { threshold: 0.1 });
observer.observe(container);
ne_110m(110m 解析度)而非 50m/10mpointsMerge(true) — 大量 points 時合併 draw callIntersectionObserver — off-screen 暫停earth-night.jpg — 夜間地球(適合 dark theme)
earth-dark.jpg — 純深色
earth-topology.png — 地形凹凸
earth-water.png — 海洋 specular
| 用途 | API |
|---|---|
| 國家上色 | polygonCapColor(feat => color) |
| 國家 click | onPolygonClick(feat => ...) |
| Hover 浮起 | onPolygonHover + polygonAltitude |
| 開發者 points | pointsData([...]).pointAltitude(d => ...) |
| Atmosphere | atmosphereColor("#3a228a") |
| Auto-rotate | controls().autoRotate = true |
| Fly-to | pointOfView({ lat, lng, altitude }, ms) |
| Responsive | world.width(w).height(h) |