Globe: Add opacity option, Part globe WIP
- Don't run the onScroll method on load, creates a funky translate otherwise - Bind window innerHeight via Svelte - Path scroll smoothing option value as prop
This commit is contained in:
@@ -31,7 +31,8 @@ class WebglGlobe {
|
|||||||
this.options = options
|
this.options = options
|
||||||
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 = 1//this.options.cameraDistance || 1 // A multiplier to move camera backward or forward
|
this.options.cameraDistance = 1 // this.options.cameraDistance || 1 // A multiplier to move camera backward or forward
|
||||||
|
this.options.opacity = this.options.opacity || 1
|
||||||
|
|
||||||
this.cities = options.markers // List of cities with their options
|
this.cities = options.markers // List of cities with their options
|
||||||
this._canUpdate = false
|
this._canUpdate = false
|
||||||
@@ -171,7 +172,7 @@ class WebglGlobe {
|
|||||||
el.style.pointerEvents = 'auto'
|
el.style.pointerEvents = 'auto'
|
||||||
el.setAttribute('href', '/location/' + markers[i].countrySlug + '/' + markers[i].slug)
|
el.setAttribute('href', '/location/' + markers[i].countrySlug + '/' + markers[i].slug)
|
||||||
el.setAttribute('sapper-noscroll', '')
|
el.setAttribute('sapper-noscroll', '')
|
||||||
if (markers[i].className) el.classList.add( markers[i].className )
|
if (markers[i].className) el.classList.add(markers[i].className)
|
||||||
|
|
||||||
// Add label
|
// Add label
|
||||||
let span = document.createElement('span')
|
let span = document.createElement('span')
|
||||||
@@ -193,6 +194,11 @@ class WebglGlobe {
|
|||||||
// Add class
|
// Add class
|
||||||
el.classList.add('marker')
|
el.classList.add('marker')
|
||||||
|
|
||||||
|
// Add a class if opacity is below 1
|
||||||
|
if (this.options.opacity < 1) {
|
||||||
|
el.classList.add('is-light')
|
||||||
|
}
|
||||||
|
|
||||||
// Callback on click
|
// Callback on click
|
||||||
el.addEventListener('click', () => {
|
el.addEventListener('click', () => {
|
||||||
this.options.onLinkClicked && this.options.onLinkClicked()
|
this.options.onLinkClicked && this.options.onLinkClicked()
|
||||||
@@ -238,7 +244,7 @@ class WebglGlobe {
|
|||||||
this.options.cameraDistance = this.height / this.$el.clientHeight;
|
this.options.cameraDistance = this.height / this.$el.clientHeight;
|
||||||
|
|
||||||
// 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.setPixelRatio(window.innerWidth < 768 ? 1 : window.devicePixelRatio)
|
||||||
this.renderer.resize(this.width , this.height)
|
this.renderer.resize(this.width , this.height)
|
||||||
|
|
||||||
// Update camera aspect ratio
|
// Update camera aspect ratio
|
||||||
@@ -277,8 +283,8 @@ class WebglGlobe {
|
|||||||
// Destroy
|
// Destroy
|
||||||
destroy() {
|
destroy() {
|
||||||
this.disable()//stop render loop
|
this.disable()//stop render loop
|
||||||
document.body.removeChild( this.$markerWrapper )
|
document.body.removeChild(this.$markerWrapper )
|
||||||
document.body.removeChild( this.renderer.canvas )
|
document.body.removeChild(this.renderer.canvas )
|
||||||
this.camera.delete()//to remove event listeners
|
this.camera.delete()//to remove event listeners
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +293,7 @@ class WebglGlobe {
|
|||||||
* This helps saving perfs and battery
|
* This helps saving perfs and battery
|
||||||
*/
|
*/
|
||||||
enable () {
|
enable () {
|
||||||
this.renderer.canvas.style.opacity = 1
|
this.renderer.canvas.style.opacity = this.options.opacity
|
||||||
this.$markerWrapper.style.opacity = 1
|
this.$markerWrapper.style.opacity = 1
|
||||||
this._canUpdate = true
|
this._canUpdate = true
|
||||||
}
|
}
|
||||||
@@ -305,7 +311,7 @@ class WebglGlobe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.globeMesh.material.uniforms.uCameraOffsetY) {
|
if (this.globeMesh.material.uniforms.uCameraOffsetY) {
|
||||||
this.globeMesh.material.uniforms.uCameraOffsetY.value += ( this.globeScrollOffset - this.globeMesh.material.uniforms.uCameraOffsetY.value ) * this.options.scrollSmoothing
|
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
|
this.currMarkerScrollOffset += (this.markersScrollOffset - this.currMarkerScrollOffset) * this.options.scrollSmoothing
|
||||||
|
|||||||
@@ -7,11 +7,13 @@
|
|||||||
import Lazy from 'svelte-lazy'
|
import Lazy from 'svelte-lazy'
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
export let type = ''
|
export let type = null
|
||||||
export let size = 0.575
|
|
||||||
export let autoRotate = true
|
export let autoRotate = true
|
||||||
|
export let scrollSmooth = 0.5
|
||||||
|
export let opacity = 1
|
||||||
let scope
|
let scope
|
||||||
let globe
|
let globe
|
||||||
|
let windowHeight
|
||||||
let containerTop = 0
|
let containerTop = 0
|
||||||
let containerHeight = 0
|
let containerHeight = 0
|
||||||
$: randomRotationPosition = getRandomArrayItem($continents.filter(continent => continent.countries)).rotation_position
|
$: randomRotationPosition = getRandomArrayItem($continents.filter(continent => continent.countries)).rotation_position
|
||||||
@@ -26,6 +28,13 @@
|
|||||||
globe.update()
|
globe.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// On scroll
|
||||||
|
const onScroll = () => {
|
||||||
|
let scrollDiff = (containerTop + windowHeight + (containerHeight - windowHeight) / 2) - document.documentElement.scrollTop
|
||||||
|
let scrollRatio = (1 - (scrollDiff / windowHeight)) * 2
|
||||||
|
globe && globe.updateCameraPos(scrollRatio, scrollDiff - windowHeight)
|
||||||
|
}
|
||||||
|
|
||||||
// On resize
|
// On resize
|
||||||
const onResize = () => {
|
const onResize = () => {
|
||||||
if (scope) {
|
if (scope) {
|
||||||
@@ -34,13 +43,7 @@
|
|||||||
}
|
}
|
||||||
globe.resize()
|
globe.resize()
|
||||||
globe.update()
|
globe.update()
|
||||||
}
|
onScroll()
|
||||||
|
|
||||||
// On scroll
|
|
||||||
const onScroll = () => {
|
|
||||||
let scrollDiff = (containerTop + window.innerHeight + (containerHeight - window.innerHeight) / 2) - document.documentElement.scrollTop
|
|
||||||
let scrollRatio = (1 - (scrollDiff / window.innerHeight)) * 2
|
|
||||||
globe && globe.updateCameraPos(scrollRatio, scrollDiff - window.innerHeight)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -58,7 +61,8 @@
|
|||||||
//cameraDistance: size, // Smaller number == larger globe
|
//cameraDistance: size, // Smaller number == larger globe
|
||||||
autoRotationSpeed: autoRotate ? -0.0025 : 0,
|
autoRotationSpeed: autoRotate ? -0.0025 : 0,
|
||||||
rotationStart: randomRotationPosition, // In degrees
|
rotationStart: randomRotationPosition, // In degrees
|
||||||
scrollSmoothing: 0.5,
|
scrollSmoothing: scrollSmooth,
|
||||||
|
opacity: opacity,
|
||||||
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 => {
|
||||||
return {
|
return {
|
||||||
@@ -71,13 +75,12 @@
|
|||||||
className: location.close ? 'is-close' : '',
|
className: location.close ? 'is-close' : '',
|
||||||
}
|
}
|
||||||
}) ],
|
}) ],
|
||||||
onLinkClicked: () => { }
|
onLinkClicked: () => {}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Run the globe
|
// Run the globe
|
||||||
onResize()
|
|
||||||
update()
|
update()
|
||||||
onScroll()
|
onResize()
|
||||||
|
|
||||||
// Enable/Disable the globe when shown/hidden
|
// Enable/Disable the globe when shown/hidden
|
||||||
const globeScroll = ScrollOut({
|
const globeScroll = ScrollOut({
|
||||||
@@ -96,6 +99,12 @@
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window on:resize={onResize} on:scroll={onScroll} />
|
<svelte:window on:scroll={onScroll} on:resize={onResize} bind:innerHeight={windowHeight} />
|
||||||
|
|
||||||
<div class="globe" class:globe--part={type === 'part'} bind:this={scope} />
|
{#if type === 'part'}
|
||||||
|
<div class="globe--part">
|
||||||
|
<div class="globe" bind:this={scope} />
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="globe" bind:this={scope} />
|
||||||
|
{/if}
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
{#if process.browser}
|
{#if process.browser}
|
||||||
<Lazy offset={window.innerHeight}>
|
<Lazy offset={window.innerHeight}>
|
||||||
<InteractiveGlobe type="part" />
|
<InteractiveGlobe type="part" opacity="0.5" />
|
||||||
</Lazy>
|
</Lazy>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|||||||
@@ -120,11 +120,7 @@
|
|||||||
|
|
||||||
{#if process.browser}
|
{#if process.browser}
|
||||||
<Lazy offset={window.innerHeight}>
|
<Lazy offset={window.innerHeight}>
|
||||||
<InteractiveGlobe size={
|
<InteractiveGlobe />
|
||||||
(winWidth <= 768) ? 0.96 :
|
|
||||||
(winWidth <= 992) ? 0.6 :
|
|
||||||
0.575}
|
|
||||||
/>
|
|
||||||
</Lazy>
|
</Lazy>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 30vw;
|
height: 30vw;
|
||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
opacity: 0.5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -102,6 +101,7 @@
|
|||||||
font-size: rem(8px);
|
font-size: rem(8px);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
@include breakpoint (sm) {
|
||||||
font-size: rem(10px);
|
font-size: rem(10px);
|
||||||
@@ -123,6 +123,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is light
|
||||||
|
&.is-light {
|
||||||
|
&.is-active {
|
||||||
|
.marker {
|
||||||
|
&__city {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
&__country {
|
||||||
|
color: #d2b7e4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Left positioned
|
// Left positioned
|
||||||
&.is-left {
|
&.is-left {
|
||||||
.marker {
|
.marker {
|
||||||
|
|||||||
@@ -92,7 +92,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Globe
|
// Globe
|
||||||
// .globe {
|
.globe--part {
|
||||||
// }
|
margin-top: 72px;
|
||||||
|
|
||||||
|
@include breakpoint (sm) {
|
||||||
|
margin-top: 136px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user