Globe: Add more props settings, Randomly position globe to a continent
- Add a little delay before restarting the rotation when hovering a marker
This commit is contained in:
@@ -7,7 +7,7 @@ import { Container, Mesh, Material, Texture, SphereGeometryBuffer, PlaneGeometry
|
||||
import GlobeVS from './globe-vs'
|
||||
import GlobeFS from './globe-fs'
|
||||
|
||||
const FOV = 1;//camera Field of view; we use 1 to prevent strong perspective effect on the globe
|
||||
const FOV = 1 // Camera Field of view; we use 1 to prevent strong perspective effect on the globe
|
||||
|
||||
/** get 3D position on a sphere from longitute lattitude */
|
||||
const lonLatToVector3 = (lng, lat) => {
|
||||
@@ -19,9 +19,8 @@ const lonLatToVector3 = (lng, lat) => {
|
||||
return [x,y,z]
|
||||
}
|
||||
|
||||
function degToRad(deg) {
|
||||
return deg * Math.PI/180
|
||||
}
|
||||
// Convert degrees to radians
|
||||
const degToRad = deg => deg * Math.PI / 180
|
||||
|
||||
|
||||
class WebglGlobe {
|
||||
@@ -162,9 +161,9 @@ class WebglGlobe {
|
||||
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;
|
||||
p[0] *= this.referenceHeight / 2
|
||||
p[1] *= this.referenceHeight / 2
|
||||
p[2] *= this.referenceHeight / 2
|
||||
|
||||
// Wrap marker in link
|
||||
let el = document.createElement('a')
|
||||
@@ -200,11 +199,15 @@ class WebglGlobe {
|
||||
|
||||
// Add class on hover
|
||||
el.addEventListener('mouseenter', () => {
|
||||
this._isHoverMarker = true
|
||||
el.classList.add('hover')
|
||||
// Stop globe rotation
|
||||
this._isHoverMarker = true
|
||||
// Clear timeout to be sure
|
||||
clearTimeout(this.hoverTimeout)
|
||||
})
|
||||
el.addEventListener('mouseleave', () => {
|
||||
this._isHoverMarker = false
|
||||
// Restart rotation after a little delay
|
||||
this.hoverTimeout = setTimeout(() => this._isHoverMarker = false, 400)
|
||||
})
|
||||
el.addEventListener('animationend', () => {
|
||||
el.classList.remove('hover')
|
||||
@@ -239,14 +242,14 @@ class WebglGlobe {
|
||||
this.camera.updateProjectionMatrix()
|
||||
|
||||
// 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._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
|
||||
*/
|
||||
this.circleScreenSize = (this.height / 2) * (1 / this.options.cameraDistance);
|
||||
this.circleScreenSize = (this.height / 2) * (1 / this.options.cameraDistance)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,7 +257,7 @@ class WebglGlobe {
|
||||
* 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) {
|
||||
this.globeScrollOffset = y;
|
||||
this.globeScrollOffset = y
|
||||
this.markersScrollOffset = scrollDiff
|
||||
|
||||
// Avoid jump due to smoothing when setting it for first time as the inital values are 0
|
||||
@@ -267,7 +270,7 @@ class WebglGlobe {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Destroy
|
||||
destroy() {
|
||||
this.disable()//stop render loop
|
||||
document.body.removeChild( this.$markerWrapper )
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script>
|
||||
import { onMount, onDestroy } from 'svelte'
|
||||
import { continents, locations } from 'utils/store'
|
||||
import { getPosition } from 'utils/functions'
|
||||
import { getPosition, getRandomArrayItem } from 'utils/functions'
|
||||
// Dependencies
|
||||
import ScrollOut from 'scroll-out'
|
||||
import Lazy from 'svelte-lazy'
|
||||
@@ -9,10 +9,12 @@
|
||||
// Props
|
||||
export let type = ''
|
||||
export let size = 0.575
|
||||
export let autoRotate = true
|
||||
let scope
|
||||
let globe
|
||||
let containerTop = 0
|
||||
let containerHeight = 0
|
||||
$: randomRotationPosition = getRandomArrayItem($continents.filter(continent => continent.countries)).rotation_position
|
||||
|
||||
|
||||
/*
|
||||
@@ -42,23 +44,20 @@
|
||||
}
|
||||
|
||||
|
||||
onDestroy(async ()=>{
|
||||
globe && globe.destroy()
|
||||
})
|
||||
|
||||
/*
|
||||
** Run code when mounted
|
||||
*/
|
||||
onMount(async () => {
|
||||
let InteractiveGlobe
|
||||
// Import libraries and code
|
||||
let InteractiveGlobe
|
||||
await import('globe/index').then(module => InteractiveGlobe = module.default)
|
||||
|
||||
// Init the globe from library
|
||||
globe = new InteractiveGlobe({
|
||||
el: scope,
|
||||
cameraDistance: size, // Smaller number == larger globe
|
||||
autoRotationSpeed: -0.0025,
|
||||
rotationStart: 90, //in degrees
|
||||
autoRotationSpeed: autoRotate ? -0.0025 : 0,
|
||||
rotationStart: randomRotationPosition, // In degrees
|
||||
scrollSmoothing: 0.5,
|
||||
texture: `/img/globe/map-${window.innerWidth > 1440 && window.devicePixelRatio > 1 ? '4k' : '2k'}.png`,
|
||||
markers: [ ...$locations.map(location => {
|
||||
@@ -72,25 +71,29 @@
|
||||
className: location.close ? 'is-close' : '',
|
||||
}
|
||||
}) ],
|
||||
centerPositions: [ ...$continents.map(continent => continent.countries) ],
|
||||
onLinkClicked: () => { }
|
||||
})
|
||||
|
||||
// Run the globe
|
||||
onResize()
|
||||
update()
|
||||
|
||||
// Enable the globe only when shown
|
||||
const globeScroll = ScrollOut({
|
||||
once: false,
|
||||
targets: scope,
|
||||
onShown: () => {
|
||||
globe.enable()
|
||||
onScroll()
|
||||
},
|
||||
|
||||
// Enable/Disable the globe when shown/hidden
|
||||
const globeScroll = ScrollOut({
|
||||
targets: scope,
|
||||
onShown: () => globe.enable(),
|
||||
onHidden: () => globe.disable()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
** Destroy when unmounted
|
||||
*/
|
||||
onDestroy(() => {
|
||||
globe && globe.destroy()
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:window on:resize={onResize} on:scroll={onScroll} />
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
data {
|
||||
id
|
||||
name
|
||||
coordinates
|
||||
rotation_position
|
||||
}
|
||||
}
|
||||
countries {
|
||||
|
||||
@@ -87,6 +87,15 @@ export const randomString = (length = 6, type = 'A') => {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Get random array item
|
||||
*/
|
||||
export const getRandomArrayItem = array => {
|
||||
const randomIndex = Math.floor(Math.random() * array.length)
|
||||
return array[randomIndex]
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Date related
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user