I have written a html with javascript to create a globe and place some markers on it. wheeler+ctrl does zooming in/out. But, When resize the window, the globe resizes accordingly but not the markers.
What I need is, When resizing the window, the globe alongwith its markers must relocate according. How can I fix this issue?
I read this: https://github.com/vasturiano/three-globe
JSFiddle Sample here to run and see
The code :
<html>
<head>
<style>
body {
margin: 0;
height: auto;
width: 100vw;
overflow: hidden;
}
#globeViz > div:nth-child(2),
#globeViz > canvas {
width: 100% !important;
height: auto !important;
min-height: 100% !important;
aspect-ratio: auto 943 / 714 !important;
}
</style>
<script src="https://unpkg.com/three"></script>
<script src="https://unpkg.com/three-globe"></script>
</head>
<body>
<div id="globeViz"></div>
<script type="importmap">
{ "imports": { "three": "https://unpkg.com/three/build/three.module.js" } }
</script>
<script type="module">
import { TrackballControls } from 'https://unpkg.com/three/examples/jsm/controls/TrackballControls.js';
import { CSS2DRenderer } from 'https://unpkg.com/three/examples/jsm/renderers/CSS2DRenderer.js';
Object.assign(THREE, { TrackballControls, CSS2DRenderer });
// marker pin icon
const markerSvg = `<svg viewBox="-4 0 36 36">
<path fill="currentColor" d="M14,0 C21.732,0 28,5.641 28,12.6 C28,23.963 14,36 14,36 C14,36 0,24.064 0,12.6 C0,5.641 6.268,0 14,0 Z"></path>
<circle fill="black" cx="14" cy="14" r="7"></circle>
</svg>`;
// Gen random data
const N = 20;
const arcsData = [...Array(N).keys()].map(() => ({
startLat: (Math.random() - 0.5) * 180,
startLng: (Math.random() - 0.5) * 360,
endLat: (Math.random() - 0.5) * 180,
endLng: (Math.random() - 0.5) * 360,
color: ['red', 'white', 'blue', 'green'][Math.round(Math.random() * 3)],
}));
const gData = [...Array(N).keys()].map(() => ({
lat: (Math.random() - 0.5) * 180,
lng: (Math.random() - 0.5) * 360,
size: 7 + Math.random() * 30,
color: ['red', 'white', 'blue', 'green'][Math.round(Math.random() * 3)],
}));
console.log(arcsData);
const Globe = new ThreeGlobe()
.globeImageUrl('https://unpkg.com/three-globe/example/img/earth-night.jpg')
.bumpImageUrl('https://unpkg.com/three-globe/example/img/earth-topology.png')
.arcsData(arcsData)
.arcColor('color')
.arcDashLength(0.4)
.arcDashGap(4)
.arcCurveResolution(1000)
.arcDashInitialGap(() => Math.random() * 5)
.arcDashAnimateTime(1000)
.htmlElementsData(gData)
.htmlElement((d) => {
const el = document.createElement('div');
el.innerHTML = markerSvg;
el.style.color = d.color;
el.style.width = `${d.size}px`;
el.style.display = el.style.zIndex > 12 ? 'block' : 'none';
return el;
});
// Initital appearance of the globe set to Sri Lanka
const lat = 7.8731; // Latitude of Sri Lanka
const lon = 80.7718; // Longitude of Sri Lanka
// Convert latitude and longitude to radians
const latRad = THREE.MathUtils.degToRad(lat);
const lonRad = THREE.MathUtils.degToRad(lon);
// Set the initial rotation to focus on Sri Lanka
Globe.rotation.x = latRad; // Rotate along the x-axis (latitude)
Globe.rotation.y = -lonRad; // Rotate along the y-axis (longitude)
Globe.rotation.z = 0; // No rotation along the z-axis
// Setup renderer
const renderers = [new THREE.WebGLRenderer({ alpha: true }), new THREE.CSS2DRenderer()];
renderers.forEach((r, idx) => {
r.setSize(window.innerWidth, window.innerHeight);
if (idx > 0) {
// overlay additional on top of main renderer
r.domElement.style.position = 'absolute';
r.domElement.style.top = '0px';
r.domElement.style.pointerEvents = 'none';
}
document.getElementById('globeViz').appendChild(r.domElement);
});
// Setup scene
const scene = new THREE.Scene();
scene.add(Globe);
scene.add(new THREE.AmbientLight(0xcccccc));
scene.add(new THREE.DirectionalLight(0xffffff, 0.6));
// Setup camera
const camera = new THREE.PerspectiveCamera();
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
camera.position.z = 268; // Zoom level
// Add camera controls
const tbControls = new THREE.TrackballControls(camera, renderers[0].domElement);
tbControls.minDistance = 101;
tbControls.rotateSpeed = 5;
tbControls.zoomSpeed = 0.8;
tbControls.object.zoom = 2;
tbControls.noZoom = true;
// Update pov when camera moves
Globe.setPointOfView(camera.position, Globe.position);
tbControls.addEventListener('change', () => Globe.setPointOfView(camera.position, Globe.position));
// Zoom in out listen ( mousewheel + ctrl)
window.addEventListener(
'mousewheel',
(e) => {
if (e.ctrlKey) {
e.preventDefault();
e.stopPropagation();
if (e.wheelDelta > 0) {
camera.position.z = camera.position.z + 10; // Zoom out
} else {
camera.position.z = camera.position.z - 10; // Zoom in
}
}
},
{ passive: false }
);
// Kick-off renderer
(function animate() {
// IIFE
// Frame cycle
tbControls.update();
renderers.forEach((r) => r.render(scene, camera));
requestAnimationFrame(animate);
})();
</script>
</body>
</html>