104 lines
3.2 KiB
JavaScript
104 lines
3.2 KiB
JavaScript
if (document.getElementById("globe")) {
|
|
(function () {
|
|
const container = document.getElementById("globe");
|
|
const canvas = container.getElementsByTagName("canvas")[0];
|
|
|
|
const globeRadius = 100;
|
|
const globeWidth = 4098 / 2;
|
|
const globeHeight = 1968 / 2;
|
|
|
|
function convertFlatCoordsToSphereCoords(x, y) {
|
|
let latitude = ((x - globeWidth) / globeWidth) * -180;
|
|
let longitude = ((y - globeHeight) / globeHeight) * -90;
|
|
latitude = (latitude * Math.PI) / 180;
|
|
longitude = (longitude * Math.PI) / 180;
|
|
const radius = Math.cos(longitude) * globeRadius;
|
|
|
|
return {
|
|
x: Math.cos(latitude) * radius,
|
|
y: Math.sin(longitude) * globeRadius,
|
|
z: Math.sin(latitude) * radius,
|
|
};
|
|
}
|
|
|
|
function makeMagic(points) {
|
|
const { width, height } = container.getBoundingClientRect();
|
|
|
|
// 1. Setup scene
|
|
const scene = new THREE.Scene();
|
|
// 2. Setup camera
|
|
const camera = new THREE.PerspectiveCamera(45, width / height);
|
|
// 3. Setup renderer
|
|
const renderer = new THREE.WebGLRenderer({
|
|
canvas,
|
|
antialias: true,
|
|
});
|
|
renderer.setSize(width, height);
|
|
// 4. Add points to canvas
|
|
// - Single geometry to contain all points.
|
|
const mergedGeometry = new THREE.Geometry();
|
|
// - Material that the dots will be made of.
|
|
const pointGeometry = new THREE.SphereGeometry(0.5, 1, 1);
|
|
const pointMaterial = new THREE.MeshBasicMaterial({
|
|
color: "#989db5",
|
|
});
|
|
|
|
for (let point of points) {
|
|
const { x, y, z } = convertFlatCoordsToSphereCoords(point.x, point.y, width, height);
|
|
|
|
if (x && y && z) {
|
|
pointGeometry.translate(x, y, z);
|
|
mergedGeometry.merge(pointGeometry);
|
|
pointGeometry.translate(-x, -y, -z);
|
|
}
|
|
}
|
|
|
|
const globeShape = new THREE.Mesh(mergedGeometry, pointMaterial);
|
|
scene.add(globeShape);
|
|
|
|
container.classList.add("peekaboo");
|
|
|
|
// Setup orbital controls
|
|
camera.orbitControls = new THREE.OrbitControls(camera, canvas);
|
|
camera.orbitControls.enableKeys = false;
|
|
camera.orbitControls.enablePan = false;
|
|
camera.orbitControls.enableZoom = false;
|
|
camera.orbitControls.enableDamping = false;
|
|
camera.orbitControls.enableRotate = true;
|
|
camera.orbitControls.autoRotate = true;
|
|
camera.position.z = -265;
|
|
|
|
function animate() {
|
|
// orbitControls.autoRotate is enabled so orbitControls.update
|
|
// must be called inside animation loop.
|
|
camera.orbitControls.update();
|
|
requestAnimationFrame(animate);
|
|
renderer.render(scene, camera);
|
|
}
|
|
animate();
|
|
}
|
|
|
|
function hasWebGL() {
|
|
const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
|
|
if (gl && gl instanceof WebGLRenderingContext) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function init() {
|
|
if (hasWebGL()) {
|
|
window;
|
|
window
|
|
.fetch("https://raw.githubusercontent.com/creativetimofficial/public-assets/master/soft-ui-dashboard-pro/assets/js/points.json")
|
|
.then((response) => response.json())
|
|
.then((data) => {
|
|
makeMagic(data.points);
|
|
});
|
|
}
|
|
}
|
|
init();
|
|
})();
|
|
}
|