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

5 years ago
  1. function init() {
  2. const container = document.getElementById('globe')
  3. const canvas = container.getElementsByTagName('canvas')[0]
  4. const width = 1000
  5. const height = 800
  6. const globeRadius = 200
  7. const globeSegments = 64
  8. const globeWidth = 4098 / 2
  9. const globeHeight = 1968 / 2
  10. const groups = {
  11. globe: null,
  12. globePoints: null,
  13. tracePoints: null,
  14. }
  15. let data, scene, renderer, globe
  16. const camera = {
  17. object: null,
  18. orbitControls: null,
  19. angles: {
  20. current: {
  21. azimuthal: null,
  22. polar: null,
  23. },
  24. target: {
  25. azimuthal: null,
  26. polar: null,
  27. },
  28. },
  29. transition: {
  30. current: 0,
  31. target: 30,
  32. },
  33. }
  34. function setup() {
  35. scene = new THREE.Scene()
  36. camera.object = new THREE.PerspectiveCamera(45, width / height, 1, 4000)
  37. camera.object.position.z = -400
  38. renderer = new THREE.WebGLRenderer({
  39. canvas: canvas,
  40. antialias: true,
  41. opacity: 1,
  42. })
  43. renderer.setSize(width, height)
  44. setupGlobe()
  45. setupOrbitControls()
  46. render()
  47. }
  48. setup()
  49. function setupGlobe() {
  50. const canvasSize = 128
  51. const textureCanvas = document.createElement('canvas')
  52. textureCanvas.width = canvasSize
  53. textureCanvas.height = canvasSize
  54. const canvasContext = textureCanvas.getContext('2d')
  55. canvasContext.rect(0, 0, canvasSize, canvasSize)
  56. const texture = new THREE.Texture(textureCanvas)
  57. const geometry = new THREE.SphereGeometry(
  58. globeRadius,
  59. globeSegments,
  60. globeSegments
  61. )
  62. const material = new THREE.MeshBasicMaterial({
  63. map: texture,
  64. transparent: true,
  65. opacity: 0.5,
  66. })
  67. globe = new THREE.Mesh(geometry, material)
  68. groups.globe = globe
  69. groups.globe.name = 'Globe'
  70. scene.add(groups.globe)
  71. addPoints()
  72. }
  73. function addPoints() {
  74. const mergedGeometry = new THREE.Geometry()
  75. const pingGeometry = new THREE.SphereGeometry(0.5, 5, 5)
  76. const material = new THREE.MeshBasicMaterial({
  77. color: '#626177',
  78. })
  79. for (let point of pointdata.points) {
  80. const pos = convertFlatCoordsToSphereCoords(point.x, point.y)
  81. if (pos.x && pos.y && pos.z) {
  82. pingGeometry.translate(pos.x, pos.y, pos.z)
  83. mergedGeometry.merge(pingGeometry)
  84. pingGeometry.translate(-pos.x, -pos.y, -pos.z)
  85. }
  86. }
  87. const total = new THREE.Mesh(mergedGeometry, material)
  88. groups.globePoints = total
  89. groups.globePoints.name = 'Globe Points'
  90. scene.add(groups.globePoints)
  91. }
  92. function addTracePoints(tracepoints) {
  93. const mergedGeometry = new THREE.Geometry()
  94. const pingGeometry = new THREE.SphereGeometry(1.9, 5, 5)
  95. const material = new THREE.MeshBasicMaterial({
  96. color: '#FF0000',
  97. })
  98. for (let point of tracepoints.points) {
  99. const pos = convertLatLngToSphereCoords(point.x, point.y)
  100. if (pos.x && pos.y && pos.z) {
  101. pingGeometry.translate(pos.x, pos.y, pos.z)
  102. mergedGeometry.merge(pingGeometry)
  103. // Reset ping item position.
  104. pingGeometry.translate(-pos.x, -pos.y, -pos.z)
  105. }
  106. }
  107. const total = new THREE.Mesh(mergedGeometry, material)
  108. groups.tracePoints = total
  109. groups.tracePoints.name = 'Trace Points'
  110. scene.add(groups.tracePoints)
  111. groups.tracePoints.rotation.y = groups.globePoints.rotation.y
  112. }
  113. init.addTracePoints = addTracePoints;
  114. function convertLatLngToSphereCoords(latitude, longitude) {
  115. const phi = (latitude * Math.PI) / 180
  116. const theta = ((longitude - 180) * Math.PI) / 180
  117. const x = -(globeRadius + -1) * Math.cos(phi) * Math.cos(theta)
  118. const y = (globeRadius + -1) * Math.sin(phi)
  119. const z = (globeRadius + -1) * Math.cos(phi) * Math.sin(theta)
  120. return new THREE.Vector3(x, y, z)
  121. }
  122. function convertFlatCoordsToSphereCoords(x, y) {
  123. // Convert latitude and longitude on the 90/180 degree axis.
  124. let latitude = ((x - globeWidth) / globeWidth) * -180
  125. let longitude = ((y - globeHeight) / globeHeight) * -90
  126. const radius = Math.cos(longitude) * globeRadius
  127. const targetX = Math.cos(latitude) * radius
  128. const targetY = Math.sin(longitude) * globeRadius
  129. const targetZ = Math.sin(latitude) * radius
  130. return {
  131. x: targetX,
  132. y: targetY,
  133. z: targetZ,
  134. }
  135. }
  136. function convertLatLngToFlatCoords(latitude, longitude) {
  137. const x = Math.round((longitude + 180) * (globeWidth / 360)) * 2
  138. const y = Math.round((-1 * latitude + 90) * (globeHeight / 180)) * 2
  139. return { x, y }
  140. }
  141. function getProjectedPosition(
  142. width,
  143. height,
  144. position,
  145. contentWidth,
  146. contentHeight
  147. ) {
  148. position = position.clone()
  149. var projected = position.project(camera.object)
  150. return {
  151. x: projected.x * width + width - contentWidth / 2,
  152. }
  153. }
  154. function returnCameraAngles(x, y) {
  155. let targetAzimuthalAngle = ((x - globeWidth) / globeWidth) * Math.PI
  156. targetAzimuthalAngle = targetAzimuthalAngle + Math.PI / 2
  157. let targetPolarAngle = (y / (globeHeight * 2)) * Math.PI
  158. return {
  159. azimuthal: targetAzimuthalAngle,
  160. polar: targetPolarAngle,
  161. }
  162. }
  163. function convertLatLngToSphereCoords(latitude, longitude) {
  164. const phi = (latitude * Math.PI) / 180
  165. const theta = ((longitude - 180) * Math.PI) / 180
  166. const x = -(globeRadius + -1) * Math.cos(phi) * Math.cos(theta)
  167. const y = (globeRadius + -1) * Math.sin(phi)
  168. const z = (globeRadius + -1) * Math.cos(phi) * Math.sin(theta)
  169. return new THREE.Vector3(x, y, z)
  170. }
  171. function easeInOutCubic(t) {
  172. return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1
  173. }
  174. function getRandomNumberBetween(min, max) {
  175. return Math.floor(Math.random() * (max - min + 1) + min)
  176. }
  177. function setupOrbitControls() {
  178. camera.orbitControls = new THREE.OrbitControls(camera.object, canvas)
  179. camera.orbitControls.enableKeys = false
  180. camera.orbitControls.enablePan = false
  181. camera.orbitControls.enableZoom = false
  182. camera.orbitControls.enableDamping = false
  183. camera.orbitControls.enableRotate = false
  184. camera.object.position.z = -550
  185. camera.orbitControls.update()
  186. }
  187. function render() {
  188. renderer.render(scene, camera.object)
  189. requestAnimationFrame(render)
  190. groups.globePoints.rotation.y += 0.01
  191. if (groups.tracePoints !== null) {
  192. groups.tracePoints.rotation.y += 0.01
  193. }
  194. }
  195. }