Parcel #8ubkocyudhuudva
Created by Anonymous
Public
Created December 22, 2024 Expires in 6 days
Loading editor...
import ThreeGlobe from "three-globe"; import * as THREE from "three"; import {OrbitControls} from "three/examples/jsm/controls/OrbitControls.js"; import * as countries from "./country_data.json"; import * as travelHistory from "./my-flights.json"; import * as airportHistory from "./my-airports.json"; export class GlobeContext { private readonly _containerElement: HTMLCanvasElement; private readonly _renderer: THREE.WebGLRenderer; private readonly _scene: THREE.Scene; private readonly _camera: THREE.PerspectiveCamera; private readonly _controls: OrbitControls; private readonly _globe: ThreeGlobe; public constructor(containerElement: HTMLCanvasElement) { this._containerElement = containerElement; // init renderer this._renderer = new THREE.WebGLRenderer({antialias: true}); this._renderer.setPixelRatio(window.devicePixelRatio); this._renderer.setSize(window.innerWidth, window.innerHeight); this._containerElement.appendChild(this._renderer.domElement); // init scene this._scene = new THREE.Scene(); this._scene.add(new THREE.AmbientLight(0xbbbbbb, 0.3)); this._scene.background = new THREE.Color(0x040d21); this._scene.fog = new THREE.Fog(0x535ef3, 400, 2000); // init camera this._camera = new THREE.PerspectiveCamera(); this._camera.aspect = window.innerWidth / window.innerHeight; this._camera.updateProjectionMatrix(); this._camera.position.z = 400; this._camera.position.x = 0; this._camera.position.y = 0; // add camera to the scene this._scene.add(this._camera); // init lights const dLight = new THREE.DirectionalLight(0xffffff, 0.8); const dLight1 = new THREE.DirectionalLight(0x7982f6, 1); const pLight = new THREE.PointLight(0x8566cc, 0.5); dLight.position.set(-800, 2000, 400); dLight1.position.set(-200, 500, 200); pLight.position.set(-200, 500, 200); this._camera.add(dLight); this._camera.add(dLight1); this._camera.add(pLight); // init helpers // const axesHelper = new AxesHelper(800); // const helper = new DirectionalLightHelper(dLight); // const helperCamera = new CameraHelper(dLight.shadow.camera); // this._scene.add(axesHelper); // this._scene.add(helper); // this._scene.add(helperCamera); // init controls this._controls = new OrbitControls(this._camera, this._renderer.domElement); this._controls.enableDamping = true; this._controls.dampingFactor = 0.01; this._controls.enablePan = false; this._controls.minDistance = 200; this._controls.maxDistance = 500; this._controls.rotateSpeed = 0.8; this._controls.zoomSpeed = 1; this._controls.autoRotate = false; this._controls.minPolarAngle = Math.PI / 3.5; this._controls.maxPolarAngle = Math.PI - Math.PI / 3; this._globe = GlobeContext.createGlobe(); this._scene.add(this._globe); window.addEventListener("resize", () => this.onWindowResize(), false); } private static createGlobe(): ThreeGlobe { const globe = new ThreeGlobe({ waitForGlobeReady: true, animateIn: true, }) .hexPolygonsData(countries.features) .hexPolygonResolution(3) .hexPolygonMargin(0.7) .showAtmosphere(true) .atmosphereColor("#3a228a") .atmosphereAltitude(0.25) .hexPolygonColor((e: { properties: { ISO_A3: string } }) => { if (["KGZ", "KOR", "THA", "RUS", "UZB", "IDN", "KAZ", "MYS"].includes(e.properties.ISO_A3)) { return "rgba(255,255,255, 1)"; } else return "rgba(255,255,255, 0.7)"; }); // NOTE Arc animations are followed after the globe enters the scene setTimeout(() => { globe.arcsData(travelHistory.flights) .arcColor((e: { status: boolean; }) => e.status ? "#9cff00" : "#FF4000") .arcAltitude((e: { arcAlt: number }) => e.arcAlt) .arcStroke((e: { status: boolean }) => e.status ? 0.5 : 0.3) .arcDashLength(0.9) .arcDashGap(4) .arcDashAnimateTime(1000) .arcsTransitionDuration(1000) .arcDashInitialGap((e: { order: number }) => e.order) .labelsData(airportHistory.airports) .labelColor(() => "#ffcb21") .labelDotOrientation((e: { text: string }) => e.text === "ALA" ? "top" : "right") .labelDotRadius(0.3) .labelSize((e: { size: number }) => e.size) .labelText("city") .labelResolution(6) .labelAltitude(0.01) .pointsData(airportHistory.airports) .pointColor(() => "#ffffff") .pointsMerge(true) .pointAltitude(0.07) .pointRadius(0.05); }, 1000); globe.rotateY(-Math.PI * (5 / 9)); globe.rotateZ(-Math.PI / 6); const globeMaterial = globe.globeMaterial() as THREE.Material; // @ts-ignore globeMaterial.color = new THREE.Color(0x3a228a); // @ts-ignore globeMaterial.emissive = new THREE.Color(0x220038); // @ts-ignore globeMaterial.emissiveIntensity = 0.1; // @ts-ignore globeMaterial.shininess = 0.7; // @ts-ignore globeMaterial.wireframe = true; return globe; } private onWindowResize() { this._camera.aspect = window.innerWidth / window.innerHeight; this._camera.updateProjectionMatrix(); this._renderer.setSize(window.innerWidth, window.innerHeight); } private animate() { this._camera.lookAt(this._scene.position); this._controls.update(); this._renderer.render(this._scene, this._camera); requestAnimationFrame(() => this.animate()); } public start() { this.onWindowResize(); this.animate(); } } const el = document.querySelector("#globeContainer") const globe = new GlobeContext(el as HTMLCanvasElement); globe.start();