Project_GRANITE / pages /modules /Bonus /GlobeBad.html
mswhite's picture
Upload 114 files
19e1977 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Globe</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { display: block; }
</style>
</head>
<body>
<!-- Three.js core -->
<script src="https://unpkg.com/three@0.128.0/build/three.min.js"></script>
<!-- OrbitControls for mouse interaction -->
<script src="https://unpkg.com/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
<script>
// 1) Boilerplate: scene, camera, renderer
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000011);
const camera = new THREE.PerspectiveCamera(
50, window.innerWidth / window.innerHeight, 1, 2000
);
camera.position.set(0, 0, 400);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 2) OrbitControls: drag to rotate, scroll to zoom
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.1;
controls.enablePan = false;
controls.minDistance = 250;
controls.maxDistance = 800;
controls.rotateSpeed = 0.6;
controls.zoomSpeed = 1.2;
// 3) Container for all country wires
const globe = new THREE.Group();
scene.add(globe);
// 4) Load GeoJSON and convert each polygon into a THREE.Line
fetch('https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson')
.then(r => r.json())
.then(geojson => {
const R = 200; // globe radius
const mat = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 1 });
geojson.features.forEach(f => {
let polys = [];
if (f.geometry.type === 'Polygon') {
polys = f.geometry.coordinates;
} else if (f.geometry.type === 'MultiPolygon') {
// flatten one level
polys = f.geometry.coordinates.flat();
}
polys.forEach(poly => {
const pts = poly.map(([lon, lat]) => {
// Map lon, lat → spherical coords
// const phi = (90 - lat) * Math.PI / 180;
// const theta = (lon + 180) * Math.PI / 180;
const phi = -1 * (lat - 90) * (Math.PI / 180);
const theta = lon * (Math.PI / 180);
return new THREE.Vector3(
R * Math.sin(phi) * Math.cos(theta),
R * Math.cos(phi),
R * Math.sin(phi) * Math.sin(theta)
);
});
// close the ring
if (pts.length > 0) pts.push(pts[0].clone());
const geo = new THREE.BufferGeometry().setFromPoints(pts);
globe.add(new THREE.Line(geo, mat));
});
});
})
.catch(err => console.error('GeoJSON load error:', err));
// 5) Handle resize
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// 6) Render loop
(function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
})();
</script>
</body>
</html>