You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

230 lines
5.9 KiB

function init() {
const container = document.getElementById('globe')
const canvas = container.getElementsByTagName('canvas')[0]
const width = 1000
const height = 800
const globeRadius = 200
const globeSegments = 64
const globeWidth = 4098 / 2
const globeHeight = 1968 / 2
const groups = {
globe: null,
globePoints: null,
tracePoints: null,
}
let data, scene, renderer, globe
const camera = {
object: null,
orbitControls: null,
angles: {
current: {
azimuthal: null,
polar: null,
},
target: {
azimuthal: null,
polar: null,
},
},
transition: {
current: 0,
target: 30,
},
}
function setup() {
scene = new THREE.Scene()
camera.object = new THREE.PerspectiveCamera(45, width / height, 1, 4000)
camera.object.position.z = -400
renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true,
opacity: 1,
})
renderer.setSize(width, height)
setupGlobe()
setupOrbitControls()
render()
}
setup()
function setupGlobe() {
const canvasSize = 128
const textureCanvas = document.createElement('canvas')
textureCanvas.width = canvasSize
textureCanvas.height = canvasSize
const canvasContext = textureCanvas.getContext('2d')
canvasContext.rect(0, 0, canvasSize, canvasSize)
const texture = new THREE.Texture(textureCanvas)
const geometry = new THREE.SphereGeometry(
globeRadius,
globeSegments,
globeSegments
)
const material = new THREE.MeshBasicMaterial({
map: texture,
transparent: true,
opacity: 0.5,
})
globe = new THREE.Mesh(geometry, material)
groups.globe = globe
groups.globe.name = 'Globe'
scene.add(groups.globe)
addPoints()
}
function addPoints() {
const mergedGeometry = new THREE.Geometry()
const pingGeometry = new THREE.SphereGeometry(0.5, 5, 5)
const material = new THREE.MeshBasicMaterial({
color: '#626177',
})
for (let point of pointdata.points) {
const pos = convertFlatCoordsToSphereCoords(point.x, point.y)
if (pos.x && pos.y && pos.z) {
pingGeometry.translate(pos.x, pos.y, pos.z)
mergedGeometry.merge(pingGeometry)
pingGeometry.translate(-pos.x, -pos.y, -pos.z)
}
}
const total = new THREE.Mesh(mergedGeometry, material)
groups.globePoints = total
groups.globePoints.name = 'Globe Points'
scene.add(groups.globePoints)
}
function addTracePoints(tracepoints) {
const mergedGeometry = new THREE.Geometry()
const pingGeometry = new THREE.SphereGeometry(1.9, 5, 5)
const material = new THREE.MeshBasicMaterial({
color: '#FF0000',
})
for (let point of tracepoints.points) {
const pos = convertLatLngToSphereCoords(point.x, point.y)
if (pos.x && pos.y && pos.z) {
pingGeometry.translate(pos.x, pos.y, pos.z)
mergedGeometry.merge(pingGeometry)
// Reset ping item position.
pingGeometry.translate(-pos.x, -pos.y, -pos.z)
}
}
const total = new THREE.Mesh(mergedGeometry, material)
groups.tracePoints = total
groups.tracePoints.name = 'Trace Points'
scene.add(groups.tracePoints)
groups.tracePoints.rotation.y = groups.globePoints.rotation.y
}
init.addTracePoints = addTracePoints;
function convertLatLngToSphereCoords(latitude, longitude) {
const phi = (latitude * Math.PI) / 180
const theta = ((longitude - 180) * Math.PI) / 180
const x = -(globeRadius + -1) * Math.cos(phi) * Math.cos(theta)
const y = (globeRadius + -1) * Math.sin(phi)
const z = (globeRadius + -1) * Math.cos(phi) * Math.sin(theta)
return new THREE.Vector3(x, y, z)
}
function convertFlatCoordsToSphereCoords(x, y) {
// Convert latitude and longitude on the 90/180 degree axis.
let latitude = ((x - globeWidth) / globeWidth) * -180
let longitude = ((y - globeHeight) / globeHeight) * -90
const radius = Math.cos(longitude) * globeRadius
const targetX = Math.cos(latitude) * radius
const targetY = Math.sin(longitude) * globeRadius
const targetZ = Math.sin(latitude) * radius
return {
x: targetX,
y: targetY,
z: targetZ,
}
}
function convertLatLngToFlatCoords(latitude, longitude) {
const x = Math.round((longitude + 180) * (globeWidth / 360)) * 2
const y = Math.round((-1 * latitude + 90) * (globeHeight / 180)) * 2
return { x, y }
}
function getProjectedPosition(
width,
height,
position,
contentWidth,
contentHeight
) {
position = position.clone()
var projected = position.project(camera.object)
return {
x: projected.x * width + width - contentWidth / 2,
}
}
function returnCameraAngles(x, y) {
let targetAzimuthalAngle = ((x - globeWidth) / globeWidth) * Math.PI
targetAzimuthalAngle = targetAzimuthalAngle + Math.PI / 2
let targetPolarAngle = (y / (globeHeight * 2)) * Math.PI
return {
azimuthal: targetAzimuthalAngle,
polar: targetPolarAngle,
}
}
function convertLatLngToSphereCoords(latitude, longitude) {
const phi = (latitude * Math.PI) / 180
const theta = ((longitude - 180) * Math.PI) / 180
const x = -(globeRadius + -1) * Math.cos(phi) * Math.cos(theta)
const y = (globeRadius + -1) * Math.sin(phi)
const z = (globeRadius + -1) * Math.cos(phi) * Math.sin(theta)
return new THREE.Vector3(x, y, z)
}
function easeInOutCubic(t) {
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1
}
function getRandomNumberBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
function setupOrbitControls() {
camera.orbitControls = new THREE.OrbitControls(camera.object, canvas)
camera.orbitControls.enableKeys = false
camera.orbitControls.enablePan = false
camera.orbitControls.enableZoom = false
camera.orbitControls.enableDamping = false
camera.orbitControls.enableRotate = false
camera.object.position.z = -550
camera.orbitControls.update()
}
function render() {
renderer.render(scene, camera.object)
requestAnimationFrame(render)
groups.globePoints.rotation.y += 0.01
if (groups.tracePoints !== null) {
groups.tracePoints.rotation.y += 0.01
}
}
}