Viewer: Finally fix Carousel navigation depending on URL

- Instead of detecting every case using popState event or whatnot, used a Sapper page stores subscribe to go to the current photo from the URL param (findIndex in photos)
- No page transition when navigating between photos in Viewer, but runs In and Out
- Also shortened dispatches to direct value over an object
This commit is contained in:
2020-03-29 18:13:27 +02:00
parent 25fa9e1c07
commit ca07fe364e
6 changed files with 73 additions and 81 deletions

View File

@@ -18,13 +18,12 @@
// Props
export let photos
export let viewer = false
export let init = undefined
// Variables
const dispatch = createEventDispatcher()
const { page } = stores()
let scope
let hover
let swiped
let currentIndex = 0
$: currentPhoto = photos[currentIndex] || null
$: prevPhoto = photos[currentIndex - 1] || photos[photos.length - 1]
@@ -34,11 +33,6 @@
/*
** Navigate to a photo
*/
// Go to specific photo on Init
if (init) {
currentIndex = photos.findIndex(photo => photo.slug === init.params.photo)
}
// Change current index from param
const goToPhoto = to => {
if (to === 'prev') {
@@ -52,25 +46,50 @@
}
// Dispatch current photo
sendCurrentPhoto()
dispatch('photoChange', photos[currentIndex])
// Reset fullscreen value if open
fullscreen.set()
if ($fullscreen) fullscreen.set()
}
// Send current photo to event
const sendCurrentPhoto = (init = false) => {
dispatch('photoChange', {
currentPhoto: photos[currentIndex],
init
})
// Hover on controls
const hoverPhoto = event => {
const button = event.currentTarget.querySelector('button')
const photoActive = scope.querySelector('.gallery__photo--active')
let photoToHover
if (event.currentTarget.dataset.to === 'prev') {
photoToHover = (photoActive.previousSibling != null) ? photoActive.previousSibling : photoActive.parentNode.lastChild
} else {
photoToHover = (photoActive.nextSibling != null) ? photoActive.nextSibling : photoActive.parentNode.firstChild
}
// Toggle class and focus of the button
if (event.type === 'mouseenter') {
photoToHover.classList.add('hover')
button.classList.add('hover')
} else if (event.type === 'mouseleave') {
photoToHover.classList.remove('hover')
button.classList.remove('hover')
}
}
// Open fullscreen
const openFullscreen = event => {
if (!swiped) {
fullscreen.set(currentPhoto)
}
// Reset swiped event if fired
swiped = false
}
/*
** Drag/touch navigation
** Navigation
*/
// Drag and swipe
const swipe = directions => {
swiped = true
if (directions.right) {
goToPhoto('prev')
} else if (directions.left) {
@@ -78,10 +97,7 @@
}
}
/*
** Keyboard navigation
*/
// Keyboard navigation
const keyboardNav = event => {
if ([37,80,74].includes(event.keyCode)) {
goToPhoto('prev')
@@ -103,30 +119,10 @@
// Enable gestures
const touch = SwipeListener(scope)
// Controls hover
hover = event => {
const button = event.currentTarget.querySelector('button')
const photoActive = document.querySelector('.gallery__photo--active')
let photoToHover
if (event.currentTarget.dataset.to === 'prev') {
photoToHover = (photoActive.previousSibling != null) ? photoActive.previousSibling : photoActive.parentNode.lastChild
} else {
photoToHover = (photoActive.nextSibling != null) ? photoActive.nextSibling : photoActive.parentNode.firstChild
}
// Toggle class and focus of the button
if (event.type === 'mouseenter') {
photoToHover.classList.add('hover')
button.classList.add('hover')
} else if (event.type === 'mouseleave') {
photoToHover.classList.remove('hover')
button.classList.remove('hover')
}
// Viewer: Navigate to photo on init and URL change
if (viewer) {
page.subscribe(page => goToPhoto(photos.findIndex(photo => photo.slug === page.params.photo)))
}
// Dispatch current photo for init
sendCurrentPhoto({ init: true })
})
</script>
@@ -145,7 +141,7 @@
class:gallery__photo--prev={photo === prevPhoto}
class:gallery__photo--active={photo === currentPhoto}
class:gallery__photo--next={photo === nextPhoto}
on:click={event => fullscreen.set(currentPhoto)}
on:click={openFullscreen}
>
<source media="(min-width: 968px)" srcset={getThumbnail(photo.image.private_hash, 1400)}>
<source media="(min-width: 800px)" srcset={getThumbnail(photo.image.private_hash, 900)}>
@@ -158,7 +154,7 @@
<div class="carousel__controls">
<div class="carousel__area carousel__area--prev" data-to="prev"
on:mouseenter={hover} on:mouseleave={hover}
on:mouseenter={hoverPhoto} on:mouseleave={hoverPhoto}
on:click={() => goToPhoto('prev')}
>
<button class="button-control button-control--white dir-left" aria-label="Previous">
@@ -168,7 +164,7 @@
</div>
<div class="carousel__area carousel__area--next" data-to="next"
on:mouseenter={hover} on:mouseleave={hover}
on:mouseenter={hoverPhoto} on:mouseleave={hoverPhoto}
on:click={() => goToPhoto('next')}
>
<button class="button-control button-control--white dir-right" aria-label="Next">
@@ -205,7 +201,7 @@
</div>
<PaginationDots className="carousel__dots" {photos} {currentIndex}
on:goToIndex={event => currentIndex = event.detail.index}
on:goToIndex={event => currentIndex = event.detail}
/>
</div>
{/if}