diff --git a/src/globe/beam/Camera.js b/src/globe/beam/Camera.js
index 4028a8d..ce4614a 100755
--- a/src/globe/beam/Camera.js
+++ b/src/globe/beam/Camera.js
@@ -247,6 +247,8 @@ class Camera extends Object3d {
this._isPointerDown = true;
+ this._pointerParent.classList.add('is-grabbing')
+
this.touchEvent = TOUCH ? (event.touches[0] || event.changedTouches[0]) : event;
this.touchEventPageX = this.touchEvent.pageX;
@@ -273,7 +275,7 @@ class Camera extends Object3d {
return;
}
- event.preventDefault();
+ // event.preventDefault();
this.touchEvent = TOUCH ? (event.touches[0] || event.changedTouches[0]) : event;
this.touchEventPageX = this.touchEvent.pageX;
@@ -281,6 +283,7 @@ class Camera extends Object3d {
this.touchEventPageX -= window.pageXOffset || document.documentElement.scrollLeft;
this.touchEventPageY -= window.pageYOffset || document.documentElement.scrollTop;
+
if (this.isRightClick) {
this.pointerXMove = this.startPointerX + (this.touchEventPageX - this.pointerXDown);
this.pointerYMove = this.startPointerY + (this.touchEventPageY - this.pointerYDown);
@@ -291,6 +294,11 @@ class Camera extends Object3d {
this.theta = this.thetaDown + ( this.pointerXOrbiter / this.winWidth * 2 * Math.PI);
this.phi = this.phiDown + ( this.pointerYOrbiter / this.winHeight * 2 * Math.PI * -1);
this.phi = Math.max( this._minPolarAngle, Math.min( this._maxPolarAngle, this.phi ) );
+
+ if( TOUCH ) {
+ this.phi = 0;
+ }
+
}
@@ -299,6 +307,7 @@ class Camera extends Object3d {
_onPointerUp() {
this._isPointerDown = false;
this.isRightClick = false;
+ this._pointerParent.classList.remove('is-grabbing')
}
update(force) {
diff --git a/src/globe/beam/Texture.js b/src/globe/beam/Texture.js
index bda6ab5..0b2c2fa 100755
--- a/src/globe/beam/Texture.js
+++ b/src/globe/beam/Texture.js
@@ -218,6 +218,7 @@ Texture.fromUrl = function(gl, url, options) {
img.onload = null;
img.onerror = null;
TEXTURE_CACHE[url] = img;
+ options && options.loaded && options.loaded()
texture.bindImage(img);
};
diff --git a/src/globe/index.js b/src/globe/index.js
index 74cef24..6b31f05 100644
--- a/src/globe/index.js
+++ b/src/globe/index.js
@@ -11,11 +11,11 @@ import GlobeFS from './globe-fs'
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? [
- parseInt(result[1], 16) / 255,
- parseInt(result[2], 16) / 255,
- parseInt(result[3], 16) / 255
- ] : [0,0,0];
- }
+ parseInt(result[1], 16) / 255,
+ parseInt(result[2], 16) / 255,
+ parseInt(result[3], 16) / 255
+ ] : [0,0,0];
+}
function lonLatToVector3(lng, lat) {
var phi = (90-lat)*(Math.PI/180),
@@ -29,6 +29,12 @@ function lonLatToVector3(lng, lat) {
class WebglGlobe {
// Constructor
constructor (options) {
+
+ //camera position cache
+ this.cameraX = 0;
+ this.cameraY = 0;
+ this.cameraZ = 0;
+
this.options = options;
this.$el = options.el;
this.cities = options.markers
@@ -50,29 +56,38 @@ class WebglGlobe {
// Build
buildWebglScene () {
this.renderer = new Renderer({
- alpha: this.alpha,
- antialias: this.antialias,
+ alpha: this.alpha,
+ antialias: window.innerWidth < 768 ? true : false,// this.antialias,
});
this.$el.appendChild(this.renderer.canvas);
- this.texture = Texture.fromUrl(this.renderer.gl, this.options.texture)
+ this.texture = Texture.fromUrl(this.renderer.gl, this.options.texture, {
+ loaded: ()=>{
+ requestAnimationFrame(()=>{
+ requestAnimationFrame(()=>{
+ this.imageLoaded = true;
+ })
+ })
+ }
+ })
this.scene = new Container()
- this.camera = new Camera({
- fov: settings.fov,
- near: 1,
- far: settings.cameraFar,
- type: 'perspective',
- orbitControl: true,
- firstPerson: false,
- lookAt: [0,0,0],
- position: [0,0, (3) / 2 / Math.tan(Math.PI * settings.fov / 360)],
+ this.camera = new Camera({
+ fov: settings.fov,
+ near: 1,
+ far: settings.cameraFar,
+ type: 'perspective',
+ orbitControl: true,
+ firstPerson: false,
+ lookAt: [0,0,0],
+ position: [0,0, (this.options.cameraDistance) / 2 / Math.tan(Math.PI * settings.fov / 360)],
+ pointerParent: this.$el
});
this.camera.lookAt = vec3.create()
this.inverseViewProjectionMatrix = mat4.create()
- this.viewProjectionMatrix = mat4.create()
- this.cameraDirection = vec3.create();
+ this.viewProjectionMatrix = mat4.create()
+ this.cameraDirection = vec3.create();
this.cameraPosition = vec3.create();
this.globeMesh = new Mesh();
@@ -90,7 +105,6 @@ class WebglGlobe {
})
this.scene.add( this.globeMesh )
-
this.markers = []
let markers = this.cities
@@ -108,18 +122,32 @@ class WebglGlobe {
widthSegments: 10, heightSegments: 10
})
let p = lonLatToVector3( markers[i].lng, markers[i].lat )
- markerMesh.position[0] = p[0] * 1.
- markerMesh.position[1] = p[1] * 1.
- markerMesh.position[2] = p[2] * 1.
+
+ markerMesh.position[0] = p[0]
+ markerMesh.position[1] = p[1]
+ markerMesh.position[2] = p[2]
this.scene.add( markerMesh )
- let el = document.createElement('div')
+ let el = document.createElement('a')
+ el.setAttribute('href', '/location/' + markers[i].countrySlug + '/' + markers[i].slug )
+ el.setAttribute('sapper-noscroll','')
let span = document.createElement('span')
- span.innerHTML = markers[i].name
+ span.classList.add('marker__label')
el.appendChild(span)
+
el.addEventListener('click', ()=>{
- alert('click on ' + markers[i].name)
+ this.options.onLinkClicked && this.options.onLinkClicked()
})
+
+ let spanCity = document.createElement('span')
+ spanCity.classList.add('marker__city')
+ spanCity.innerHTML = markers[i].name;
+ span.appendChild(spanCity)
+ let spanCountry = document.createElement('span')
+ spanCountry.classList.add('marker__country')
+ spanCountry.innerHTML = markers[i].countryName;
+ span.appendChild(spanCountry)
+
el.classList.add('marker')
this.$el.appendChild( el )
this.markers.push({
@@ -135,14 +163,17 @@ class WebglGlobe {
resize () {
this.width = this.$el.clientWidth;
this.height = this.$el.clientHeight;
+
+ // console.log('GLOBE RESIZE', this.width, this.height)
+
settings.resolution[0] = this.width //* settings.devicePixelRatio
settings.resolution[1] = this.height //* settings.devicePixelRatio
if (!this.supportWebgl) {
return
}
- this.renderer.setPixelRatio(settings.devicePixelRatio);
- this.renderer.resize(settings.resolution[0], settings.resolution[1])
- this.camera.aspect = settings.resolution[0] / settings.resolution[1]
+ this.renderer.setPixelRatio(window.innerWidth < 768 ? 1 : settings.devicePixelRatio);
+ this.renderer.resize(settings.resolution[0], settings.resolution[1])
+ this.camera.aspect = settings.resolution[0] / settings.resolution[1]
this.camera.updateProjectionMatrix()
@@ -168,13 +199,13 @@ class WebglGlobe {
let refPos = vec3.create()
vec3.set(refPos, 0, 1, 0 )
vec3.transformMat4(refPos, refPos, this.viewProjectionMatrix);
- let refx = ( (refPos[0] + 1) / 2) * window.innerWidth
- let refy = (1. - (refPos[1] + 1) / 2) * window.innerHeight
+ let refx = ( (refPos[0] + 1) / 2) * this.width
+ let refy = (1. - (refPos[1] + 1) / 2) * this.height
let dir2 = vec2.create()
vec2.set( dir2, refx, refy )
let center2 = vec2.create()
- vec2.set( center2, window.innerWidth/2, window.innerHeight/2 )
+ vec2.set( center2, this.width/2, this.height/2 )
let dir2d2 = vec2.clone(dir2, dir2)
vec2.subtract( dir2d2, dir2d2, center2 )
this.circleScreenSize = vec2.length( dir2d2 ) * 1.04
@@ -187,11 +218,6 @@ class WebglGlobe {
return;
}
- // this.currPointer[0] += ( this.pointerRatio[0] - this.currPointer[0]) * 0.05
- // this.currPointer[1] += ( this.pointerRatio[1] - this.currPointer[1]) * 0.05
- // this.globeMesh.rotation[1] = this.currPointer[0]
- // this.globeMesh.rotation[2] = this.currPointer[1]
-
//manually call this as we prevent ithe camera from update between passes
this.camera.update();
vec3.set(this.cameraPosition, this.camera.worldMatrix[12], this.camera.worldMatrix[13], this.camera.worldMatrix[14]);
@@ -202,15 +228,29 @@ class WebglGlobe {
mat4.multiply(this.viewProjectionMatrix, this.viewProjectionMatrix, this.camera.inverseWorldMatrix);
mat4.invert(this.inverseViewProjectionMatrix, this.viewProjectionMatrix);
+ let needsUpdate = false;
+ if (this.cameraX != this.camera.worldMatrix[12] ||
+ this.cameraY != this.camera.worldMatrix[13] ||
+ this.cameraZ != this.camera.worldMatrix[14]) {
+ this.cameraX = this.camera.worldMatrix[12];
+ this.cameraY = this.camera.worldMatrix[13];
+ this.cameraZ = this.camera.worldMatrix[14];
+ needsUpdate = true;
+ }
+ if (!needsUpdate && this.imageLoaded) {
+ return
+ }
+
+ // console.log('RENDER WEBGL')
let screenPos = vec3.create()
this.markers.forEach((marker, i)=>{
vec3.set(screenPos, marker.position[0], marker.position[1], marker.position[2] )
vec3.transformMat4(screenPos, screenPos, this.viewProjectionMatrix);
- let x = ( (screenPos[0] + 1) / 2) * window.innerWidth
- let y = (1. - (screenPos[1] + 1) / 2) * window.innerHeight
+ let x = ( (screenPos[0] + 1) / 2) * this.width
+ let y = (1. - (screenPos[1] + 1) / 2) * this.height
let N = vec3.create()
vec3.set( N, marker.position[0], marker.position[1], marker.position[2] )
@@ -222,11 +262,11 @@ class WebglGlobe {
vec3.normalize( V, V );
//behind
- if ( vec3.dot( V, N ) * -1 < 0) {
+ if ( vec3.dot( V, N ) * -1 < 0 ) {
let dir = vec2.create()
vec2.set( dir, x, y )
let center = vec2.create()
- vec2.set( center, window.innerWidth/2, window.innerHeight/2 )
+ vec2.set( center, this.width/2, this.height/2 )
let dir2d = vec2.clone(dir, dir)
vec2.subtract( dir2d, dir2d, center )
vec2.normalize( dir2d, dir2d );
@@ -247,39 +287,6 @@ class WebglGlobe {
this.renderer.clear()
this.renderer.render(this.scene, this.camera);
}
-
- // initPointer() {
- // this.currPointer = [0,0]
- // this.pointer = [0,0]
- // this.pointerRatio = [0,0]
- // this._onPointerDown = this._onPointerDown.bind(this)
- // this._onPointerMove = this._onPointerMove.bind(this)
- // this._onPointerUp = this._onPointerUp.bind(this)
- // this._handleOrientation = this._handleOrientation.bind(this)
- // document.addEventListener(support.pointerdown, this._onPointerDown, false);
- // document.addEventListener(support.pointermove, this._onPointerMove, false);
- // document.addEventListener(support.pointerup, this._onPointerUp, false);
- // window.addEventListener('deviceorientation', this._handleOrientation);
- // }
- // _handleOrientation(event) {
- // this.pointerRatio[0] = (event.gamma) / 25
- // this.pointerRatio[1] = (event.beta-45) / 25
- // }
- // _onPointerDown() {
- // this._isPointerDown = true;
- // }
- // _onPointerUp() {
- // this._isPointerDown = false
- // }
- // _onPointerMove(event) {
- // let pe = support.touch && event.type != 'mousemove' ? (event.touches[0] || event.changedTouches[0]) : event;
- // this.pointer[0] = pe.pageX;
- // this.pointer[1] = pe.pageY;
- // this.pointer[1] -= window.pageYOffset || document.documentElement.scrollTop
- // this.pointerRatio[0] = (this.pointer[0] / window.innerWidth - .5) * 2
- // this.pointerRatio[1] = (this.pointer[1] / window.innerHeight - .5) * 2
- // }
-
}
// window.WebglGlobe = WebglGlobe
diff --git a/src/molecules/InteractiveGlobe.svelte b/src/molecules/InteractiveGlobe.svelte
index 11046b0..2033c8e 100644
--- a/src/molecules/InteractiveGlobe.svelte
+++ b/src/molecules/InteractiveGlobe.svelte
@@ -8,7 +8,10 @@
let globe
// Functions
- const resize = () => globe.resize()
+ const resize = () => {
+ globe.resize()
+ globe.update()
+ }
const update = () => {
requestAnimationFrame(update)
globe.update()
@@ -20,37 +23,36 @@
*/
onMount(async () => {
// For browser only
- // if (process.browser) {
- // // Import libraries and code
- // let WebglGlobe
- // await import('globe').then(module => WebglGlobe = module.default)
+ if (process.browser) {
+ // Import libraries and code
+ let WebglGlobe
+ await import('globe').then(module => WebglGlobe = module.default)
- // // Init the globe from library
- // globe = new WebglGlobe({
- // el: scope,
- // texture: '/img/globe/map-4k.png',
- // markers: [...$locations.map(location => {
- // return {
- // name: location.name,
- // slug: location.slug,
- // countrySlug: location.country.slug,
- // lat: location.coordinates.lat,
- // lng: location.coordinates.lng
- // }
- // })]
- // })
+ // Init the globe from library
+ globe = new WebglGlobe({
+ el: scope,
+ texture: '/img/globe/map-2k.png',
+ markers: [...$locations.map(location => {
+ return {
+ name: location.name,
+ slug: location.slug,
+ countryName: location.country.name,
+ countrySlug: location.country.slug,
+ lat: location.coordinates.lat,
+ lng: location.coordinates.lng
+ }
+ })],
+ onLinkClicked: () => {},
+ cameraDistance: 3
+ })
- // // Run the globe
- // resize()
- // update()
- // }
+ // Run the globe
+ resize()
+ update()
+ }
})
-
+