- Added visible continents to options
This commit is contained in:
@@ -23,17 +23,15 @@ class WebglGlobe {
|
||||
|
||||
// Constructor
|
||||
constructor (options) {
|
||||
|
||||
this.$el = options.el//the Dom reference node
|
||||
this.$el = options.el // The DOM reference node
|
||||
this.options = options
|
||||
this.options.autoRotationSpeed = this.options.autoRotationSpeed || 0
|
||||
this.options.scrollSmoothing = this.options.scrollSmoothing || 0.5 // smooth the globe position to avoid janks on scroll(lower==smoother)
|
||||
this.options.cameraDistance = this.options.cameraDistance || 1 //a multiplier to move camera backward or forward
|
||||
this.cities = options.markers//list of cities with their options
|
||||
|
||||
this.options.scrollSmoothing = this.options.scrollSmoothing || 0.5 // Smooth the globe position to avoid janks on scroll (lower == smoother)
|
||||
this.options.cameraDistance = this.options.cameraDistance || 1 // A multiplier to move camera backward or forward
|
||||
this.cities = options.markers // List of cities with their options
|
||||
this._canUpdate = false
|
||||
this.hasUpdateCameraPos = false
|
||||
this.referenceHeight = 1;//used to set camera distance from globe where referenceHeight == window height
|
||||
this.referenceHeight = 1 // Used to set camera distance from globe where referenceHeight == window height
|
||||
this.currMarkerScrollOffset = 0
|
||||
this.markersScrollOffset = 0
|
||||
this.globeScrollOffset = 0
|
||||
@@ -51,14 +49,13 @@ class WebglGlobe {
|
||||
this.resize()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Build
|
||||
buildWebglScene () {
|
||||
|
||||
this.renderer = new Renderer({
|
||||
//to allow transparent background on webgl canvas
|
||||
alpha: true,
|
||||
//only enable antialiasing if screen is small with no retina(for performances reasons)
|
||||
// To allow transparent background on webgl canvas
|
||||
alpha: true,
|
||||
// Enable antialiasing only if screen is small with no retina (for performances reasons)
|
||||
antialias: window.innerWidth < 768 || window.devicePixelRatio == 1 ? true : false,
|
||||
})
|
||||
|
||||
@@ -75,7 +72,7 @@ class WebglGlobe {
|
||||
// The markers DOM nodes wrapper
|
||||
// this wrapper is added just next to the canvas, at the end of body tag
|
||||
this.$markerWrapper = document.createElement('div')
|
||||
this.$markerWrapper.classList.add('markerWrapper')
|
||||
this.$markerWrapper.classList.add('globe__markers')
|
||||
this.$markerWrapper.style.position = 'fixed'
|
||||
this.$markerWrapper.style.top = 0
|
||||
this.$markerWrapper.style.left = 0
|
||||
@@ -111,9 +108,9 @@ class WebglGlobe {
|
||||
})
|
||||
this.camera.lookAt = vec3.create()
|
||||
|
||||
/**
|
||||
* used to compute screen position of markers,
|
||||
* to move the corresponding DOM nodes
|
||||
/**
|
||||
* used to compute screen position of markers,
|
||||
* to move the corresponding DOM nodes
|
||||
*/
|
||||
this.viewProjectionMatrix = mat4.create()
|
||||
this.cameraPosition = vec3.create()
|
||||
@@ -157,11 +154,11 @@ class WebglGlobe {
|
||||
// Position marker
|
||||
let p = lonLatToVector3(markers[i].lng, markers[i].lat)
|
||||
|
||||
//scale marker position to fit globe size
|
||||
// Scale marker position to fit globe size
|
||||
p[0] *= this.referenceHeight/2;
|
||||
p[1] *= this.referenceHeight/2;
|
||||
p[2] *= this.referenceHeight/2;
|
||||
|
||||
|
||||
// Wrap marker in link
|
||||
let el = document.createElement('a')
|
||||
el.style.pointerEvents = 'auto'
|
||||
@@ -211,7 +208,6 @@ class WebglGlobe {
|
||||
|
||||
// Resize method
|
||||
resize () {
|
||||
|
||||
if (!this.supportWebgl) {
|
||||
return
|
||||
}
|
||||
@@ -219,21 +215,21 @@ class WebglGlobe {
|
||||
this.width = window ? window.innerWidth : 0
|
||||
this.height = window ? window.innerHeight : 0
|
||||
|
||||
//remove retina on small screen(aka mobile) to boost perfs
|
||||
// Remove retina on small screen (aka mobile) to boost perfs
|
||||
this.renderer.setPixelRatio( window.innerWidth < 768 ? 1 : window.devicePixelRatio)
|
||||
this.renderer.resize(this.width , this.height)
|
||||
|
||||
//update camera aspect ratio
|
||||
|
||||
// Update camera aspect ratio
|
||||
this.camera.aspect = this.width / this.height
|
||||
this.camera.updateProjectionMatrix()
|
||||
|
||||
//at which distance to put the camera when rotating arounf the globe
|
||||
|
||||
// Distance to put the camera when rotating around the globe
|
||||
this.camera._cameraDistance = (this.referenceHeight * this.options.cameraDistance) / 2 / Math.tan(Math.PI * FOV / 360);
|
||||
this.camera.update(true)
|
||||
|
||||
/**
|
||||
* When markers are behind the globe, clamp their position
|
||||
* to this size to make them move along the circle edge
|
||||
/**
|
||||
* When markers are behind the globe, clamp their position
|
||||
* to this size to make them move along the circle edge
|
||||
*/
|
||||
this.circleScreenSize = (this.height / 2) * (1 / this.options.cameraDistance);
|
||||
}
|
||||
@@ -242,11 +238,11 @@ class WebglGlobe {
|
||||
* As the camera rotates arount the globe, we cant simply move the Y position of the camera or the globe
|
||||
* Instead, we move the globe vertex inside the vertex shadder after compute the project on screen, so we pass the 'scroll' position to a uniform
|
||||
*/
|
||||
updateCameraPos(y, scrollDiff) {
|
||||
updateCameraPos (y, scrollDiff) {
|
||||
this.globeScrollOffset = y;
|
||||
this.markersScrollOffset = scrollDiff
|
||||
|
||||
//avoid jump due to smoothing when setting it for first time as the inital values are 0
|
||||
|
||||
// Avoid jump due to smoothing when setting it for first time as the inital values are 0
|
||||
if (!this.hasUpdateCameraPos) {
|
||||
this.hasUpdateCameraPos = true
|
||||
if (this.globeMesh.material.uniforms.uCameraOffsetY) {
|
||||
@@ -260,17 +256,16 @@ class WebglGlobe {
|
||||
* Flag to stop rendering the webgl if the globe isnt visible
|
||||
* This helps saving perfs and battery
|
||||
*/
|
||||
enable() {
|
||||
enable () {
|
||||
this._canUpdate = true
|
||||
}
|
||||
|
||||
disable() {
|
||||
disable () {
|
||||
this._canUpdate = false
|
||||
}
|
||||
|
||||
// Update
|
||||
update () {
|
||||
|
||||
if (!this.supportWebgl || !this._canUpdate || !this.imageLoaded || !this.hasUpdateCameraPos) {
|
||||
return
|
||||
}
|
||||
@@ -281,44 +276,41 @@ class WebglGlobe {
|
||||
|
||||
this.currMarkerScrollOffset += (this.markersScrollOffset - this.currMarkerScrollOffset) * this.options.scrollSmoothing
|
||||
|
||||
//compute the camera view-projection matrix to use it on the markers
|
||||
// Compute the camera view-projection matrix to use it on the markers
|
||||
this.camera.update()
|
||||
vec3.set(this.cameraPosition, this.camera.worldMatrix[12], this.camera.worldMatrix[13], this.camera.worldMatrix[14])
|
||||
mat4.copy(this.viewProjectionMatrix, this.camera.projectionMatrix)
|
||||
mat4.multiply(this.viewProjectionMatrix, this.viewProjectionMatrix, this.camera.inverseWorldMatrix)
|
||||
|
||||
//Auto rotate the globe
|
||||
// Auto rotate the globe
|
||||
this.globeMesh.rotation[1] += this.options.autoRotationSpeed
|
||||
this.globeMesh.updateMatrix()
|
||||
this.globeMesh.updateWorldMatrix()
|
||||
|
||||
let screenPos = vec3.create()
|
||||
this.markers.forEach((marker, i) => {
|
||||
|
||||
//get marker 3D position and project it on screen to get 2D position
|
||||
// Get marker 3D position and project it on screen to get 2D position
|
||||
vec3.set(screenPos, marker.position[0], marker.position[1], marker.position[2])
|
||||
vec3.transformMat4(screenPos, screenPos, this.globeMesh.worldMatrix)
|
||||
vec3.transformMat4(screenPos, screenPos, this.viewProjectionMatrix)
|
||||
|
||||
//marker 2D screen position (starting from top left corner of screen)
|
||||
// Marker 2D screen position (starting from top left corner of screen)
|
||||
let x = ((screenPos[0] + 1) / 2) * this.width
|
||||
let y = (1. - (screenPos[1] + 1) / 2) * this.height
|
||||
|
||||
//compute marker Normal
|
||||
// Compute marker Normal
|
||||
let N = vec3.create()
|
||||
vec3.set(N, marker.position[0], marker.position[1], marker.position[2])
|
||||
vec3.transformMat4(N, N, this.globeMesh.worldMatrix)
|
||||
vec3.normalize(N, N)
|
||||
|
||||
//compute view vector (camera direction)
|
||||
// Compute view vector (camera direction)
|
||||
let V = vec3.create()
|
||||
vec3.set(V, marker.position[0], marker.position[1], marker.position[2])
|
||||
vec3.subtract(V, V, this.cameraPosition)
|
||||
vec3.normalize(V, V)
|
||||
|
||||
|
||||
|
||||
//the marker is behind the globe: clamp it to the globe edge
|
||||
// Marker is behind the globe: clamp it to the globe edge
|
||||
if (vec3.dot(V, N) * -1 < 0) {
|
||||
let dir = vec2.create()
|
||||
vec2.set(dir, x, y)
|
||||
@@ -334,7 +326,7 @@ class WebglGlobe {
|
||||
marker.el.style.transform = `translate(${dir2d[0]}px, ${dir2d[1]}px) translateZ(0)`
|
||||
marker.el.classList.remove('is-active')
|
||||
}
|
||||
//marker is in front of the globe; update 2D position
|
||||
// Marker is in front of the globe; update 2D position
|
||||
else {
|
||||
y += this.currMarkerScrollOffset
|
||||
marker.el.style.transform = `translate(${x}px, ${y}px) translateZ(0)`
|
||||
@@ -342,8 +334,8 @@ class WebglGlobe {
|
||||
}
|
||||
})
|
||||
|
||||
//render webgl frame
|
||||
this.renderer.clearColor(0,0,0,0)//[RGBA] alpha is set to 0 to have a transparent background on the webgl
|
||||
// Render WebGL frame
|
||||
this.renderer.clearColor(0,0,0,0) //[RGBA] alpha is set to 0 to have a transparent background on the webgl
|
||||
this.renderer.clear()
|
||||
this.renderer.render(this.scene, this.camera)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user