globae update
This commit is contained in:
@@ -29,11 +29,15 @@ class WebglGlobe {
|
|||||||
this.options.autoRotationSpeed = this.options.autoRotationSpeed || 0
|
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.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.options.cameraDistance = this.options.cameraDistance || 1 //a multiplier to move camera backward or forward
|
||||||
this.referenceHeight = 1;//used to set camera distance from globe where referenceHeight == window height
|
|
||||||
this._canUpdate = false
|
|
||||||
|
|
||||||
this.cities = options.markers//list of cities with their options
|
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.currMarkerScrollOffset = 0
|
||||||
|
this.markersScrollOffset = 0
|
||||||
|
this.globeScrollOffset = 0
|
||||||
|
|
||||||
let gl
|
let gl
|
||||||
let canvas = document.createElement('canvas')
|
let canvas = document.createElement('canvas')
|
||||||
try { gl = canvas.getContext('webgl') }
|
try { gl = canvas.getContext('webgl') }
|
||||||
@@ -55,7 +59,7 @@ class WebglGlobe {
|
|||||||
//to allow transparent background on webgl canvas
|
//to allow transparent background on webgl canvas
|
||||||
alpha: true,
|
alpha: true,
|
||||||
//only enable antialiasing if screen is small with no retina(for performances reasons)
|
//only enable antialiasing if screen is small with no retina(for performances reasons)
|
||||||
antialias: window.innerWidth < 768 || !window.devicePixelRatio == 1 ? true : false,
|
antialias: window.innerWidth < 768 || window.devicePixelRatio == 1 ? true : false,
|
||||||
})
|
})
|
||||||
|
|
||||||
// we put the canvas at the end of body tag as 'position:fixed'
|
// we put the canvas at the end of body tag as 'position:fixed'
|
||||||
@@ -153,6 +157,11 @@ class WebglGlobe {
|
|||||||
// Position marker
|
// Position marker
|
||||||
let p = lonLatToVector3(markers[i].lng, markers[i].lat)
|
let p = lonLatToVector3(markers[i].lng, markers[i].lat)
|
||||||
|
|
||||||
|
//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
|
// Wrap marker in link
|
||||||
let el = document.createElement('a')
|
let el = document.createElement('a')
|
||||||
el.style.pointerEvents = 'auto'
|
el.style.pointerEvents = 'auto'
|
||||||
@@ -233,10 +242,17 @@ class WebglGlobe {
|
|||||||
* As the camera rotates arount the globe, we cant simply move the Y position of the camera or the globe
|
* 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
|
* 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) {
|
updateCameraPos(y, scrollDiff) {
|
||||||
y *= 2;
|
this.globeScrollOffset = y;
|
||||||
|
this.markersScrollOffset = scrollDiff
|
||||||
|
|
||||||
|
//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) {
|
if (this.globeMesh.material.uniforms.uCameraOffsetY) {
|
||||||
this.globeMesh.material.uniforms.uCameraOffsetY.value += ( y - this.globeMesh.material.uniforms.uCameraOffsetY.value ) * this.options.scrollSmoothing
|
this.globeMesh.material.uniforms.uCameraOffsetY.value = this.globeScrollOffset
|
||||||
|
}
|
||||||
|
this.currMarkerScrollOffset = this.markersScrollOffset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,10 +271,16 @@ class WebglGlobe {
|
|||||||
// Update
|
// Update
|
||||||
update () {
|
update () {
|
||||||
|
|
||||||
if (!this.supportWebgl || !this._canUpdate || !this.imageLoaded) {
|
if (!this.supportWebgl || !this._canUpdate || !this.imageLoaded || !this.hasUpdateCameraPos) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.globeMesh.material.uniforms.uCameraOffsetY) {
|
||||||
|
this.globeMesh.material.uniforms.uCameraOffsetY.value += ( this.globeScrollOffset - this.globeMesh.material.uniforms.uCameraOffsetY.value ) * this.options.scrollSmoothing
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
this.camera.update()
|
||||||
vec3.set(this.cameraPosition, this.camera.worldMatrix[12], this.camera.worldMatrix[13], this.camera.worldMatrix[14])
|
vec3.set(this.cameraPosition, this.camera.worldMatrix[12], this.camera.worldMatrix[13], this.camera.worldMatrix[14])
|
||||||
@@ -266,7 +288,7 @@ class WebglGlobe {
|
|||||||
mat4.multiply(this.viewProjectionMatrix, this.viewProjectionMatrix, this.camera.inverseWorldMatrix)
|
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.rotation[1] += this.options.autoRotationSpeed
|
||||||
this.globeMesh.updateMatrix()
|
this.globeMesh.updateMatrix()
|
||||||
this.globeMesh.updateWorldMatrix()
|
this.globeMesh.updateWorldMatrix()
|
||||||
|
|
||||||
@@ -294,6 +316,8 @@ class WebglGlobe {
|
|||||||
vec3.subtract(V, V, this.cameraPosition)
|
vec3.subtract(V, V, this.cameraPosition)
|
||||||
vec3.normalize(V, V)
|
vec3.normalize(V, V)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//the marker is behind the globe: clamp it to the globe edge
|
//the marker is behind the globe: clamp it to the globe edge
|
||||||
if (vec3.dot(V, N) * -1 < 0) {
|
if (vec3.dot(V, N) * -1 < 0) {
|
||||||
let dir = vec2.create()
|
let dir = vec2.create()
|
||||||
@@ -305,11 +329,14 @@ class WebglGlobe {
|
|||||||
vec2.normalize(dir2d, dir2d)
|
vec2.normalize(dir2d, dir2d)
|
||||||
vec2.scale(dir2d, dir2d, this.circleScreenSize)
|
vec2.scale(dir2d, dir2d, this.circleScreenSize)
|
||||||
vec2.add(dir2d, dir2d, center)
|
vec2.add(dir2d, dir2d, center)
|
||||||
|
|
||||||
|
dir2d[1] += this.currMarkerScrollOffset
|
||||||
marker.el.style.transform = `translate(${dir2d[0]}px, ${dir2d[1]}px) translateZ(0)`
|
marker.el.style.transform = `translate(${dir2d[0]}px, ${dir2d[1]}px) translateZ(0)`
|
||||||
marker.el.classList.remove('is-active')
|
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 {
|
else {
|
||||||
|
y += this.currMarkerScrollOffset
|
||||||
marker.el.style.transform = `translate(${x}px, ${y}px) translateZ(0)`
|
marker.el.style.transform = `translate(${x}px, ${y}px) translateZ(0)`
|
||||||
marker.el.classList.add('is-active')
|
marker.el.classList.add('is-active')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,8 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
// export let type = ''
|
export let type = ''
|
||||||
let scope
|
let scope
|
||||||
let globe
|
let globe
|
||||||
let containerTop = 0
|
let containerTop = 0
|
||||||
@@ -36,6 +35,7 @@
|
|||||||
globe.resize()
|
globe.resize()
|
||||||
globe.update()
|
globe.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
const update = () => {
|
const update = () => {
|
||||||
requestAnimationFrame(update)
|
requestAnimationFrame(update)
|
||||||
globe.update()
|
globe.update()
|
||||||
@@ -43,10 +43,10 @@
|
|||||||
|
|
||||||
const onScroll = (e)=> {
|
const onScroll = (e)=> {
|
||||||
let scrollDiff = (containerTop + window.innerHeight + (containerHeight - window.innerHeight) /2 ) - document.documentElement.scrollTop
|
let scrollDiff = (containerTop + window.innerHeight + (containerHeight - window.innerHeight) /2 ) - document.documentElement.scrollTop
|
||||||
let scrollRatio = 1 - ( scrollDiff / window.innerHeight )
|
let scrollRatio = (1 - ( scrollDiff / window.innerHeight ) ) * 2
|
||||||
|
globe && globe.updateCameraPos( scrollRatio, scrollDiff - window.innerHeight)
|
||||||
globe && globe.updateCameraPos( scrollRatio )
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Run code when mounted
|
** Run code when mounted
|
||||||
*/
|
*/
|
||||||
@@ -72,8 +72,8 @@
|
|||||||
// Init the globe from library
|
// Init the globe from library
|
||||||
globe = new InteractiveGlobe({
|
globe = new InteractiveGlobe({
|
||||||
el: scope,
|
el: scope,
|
||||||
cameraDistance: 1.5,
|
cameraDistance: 0.5,//smaller number == larger globe
|
||||||
autoRotationSpeed: -0.01,
|
autoRotationSpeed: -0.0025,
|
||||||
scrollSmoothing: 0.5,
|
scrollSmoothing: 0.5,
|
||||||
texture: `/img/globe/map-${window.innerWidth > 1440 && window.devicePixelRatio > 1 ? '4k' : '2k'}.png`,
|
texture: `/img/globe/map-${window.innerWidth > 1440 && window.devicePixelRatio > 1 ? '4k' : '2k'}.png`,
|
||||||
markers: [...$locations.map(location => {
|
markers: [...$locations.map(location => {
|
||||||
@@ -99,12 +99,8 @@
|
|||||||
|
|
||||||
<svelte:window on:resize={resize} on:scroll={onScroll} />
|
<svelte:window on:resize={resize} on:scroll={onScroll} />
|
||||||
|
|
||||||
<!-- {#if type === 'part'}
|
{#if type === 'part'}
|
||||||
<div class="globe__cut">
|
<div class="globe globe--cut" bind:this={scope} />
|
||||||
<div class="globe" bind:this={scope} />
|
|
||||||
</div>
|
|
||||||
{:else}
|
{:else}
|
||||||
<div class="globe" bind:this={scope} />
|
<div class="globe" bind:this={scope} />
|
||||||
{/if} -->
|
{/if}
|
||||||
|
|
||||||
<div class="globe" bind:this={scope} />
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
// pointer-events: none;
|
// pointer-events: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
|
||||||
////DEBUG////
|
////DEBUG////
|
||||||
background: rgba(255,0,0,0.2);
|
background: rgba(255,0,0,0.2);
|
||||||
&:after {
|
&:after {
|
||||||
@@ -30,19 +31,14 @@
|
|||||||
height: 2000px;
|
height: 2000px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Cut
|
// Cut
|
||||||
&__cut {
|
&--cut {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 35vw;
|
height: 35vw;
|
||||||
min-height: 400px;
|
min-height: 400px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
// Partial globe
|
|
||||||
// .globe {
|
|
||||||
// margin-top: -18vw;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user