Keep original photos ratio if not 3/2 on Viewer
- Fix previousPage usage - Fix entering animation timings and previous photo navigation - Add fade transition on fullscreen viewer for mobile - Display date only if existing
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
import { page } from '$app/stores'
|
import { page } from '$app/stores'
|
||||||
import { goto } from '$app/navigation'
|
import { goto } from '$app/navigation'
|
||||||
import { onMount, tick } from 'svelte'
|
import { onMount, tick } from 'svelte'
|
||||||
import { scale } from 'svelte/transition'
|
import { fade, scale } from 'svelte/transition'
|
||||||
import { quartOut } from 'svelte/easing'
|
import { quartOut } from 'svelte/easing'
|
||||||
import { getAssetUrlKey } from '$utils/helpers'
|
import { getAssetUrlKey } from '$utils/helpers'
|
||||||
import { fetchAPI } from '$utils/api'
|
import { fetchAPI } from '$utils/api'
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Define previous URL
|
// Define previous URL
|
||||||
$: previousUrl = $previousPage ?? `/${location.country.slug}/${location.slug}`
|
$: previousUrl = $previousPage ? $previousPage : `/${location.country.slug}/${location.slug}`
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,7 +130,7 @@
|
|||||||
await tick()
|
await tick()
|
||||||
const picture = fullscreenEl.querySelector('picture')
|
const picture = fullscreenEl.querySelector('picture')
|
||||||
const image = fullscreenEl.querySelector('img')
|
const image = fullscreenEl.querySelector('img')
|
||||||
picture.scrollTo((image.offsetWidth - innerWidth) / 2, 0)
|
picture.scrollTo((image.offsetWidth - innerWidth / 2), 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,6 +221,7 @@
|
|||||||
const timeline: AnimeTimelineInstance = anime.timeline({
|
const timeline: AnimeTimelineInstance = anime.timeline({
|
||||||
duration: 1600,
|
duration: 1600,
|
||||||
easing: 'easeOutQuart',
|
easing: 'easeOutQuart',
|
||||||
|
autoplay: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
anime.set('.viewer__picture', {
|
anime.set('.viewer__picture', {
|
||||||
@@ -238,14 +239,14 @@
|
|||||||
duration: 900,
|
duration: 900,
|
||||||
}, 250)
|
}, 250)
|
||||||
timeline.add({
|
timeline.add({
|
||||||
targets: '.viewer__picture:not(.is-0):not(.is-1)',
|
targets: '.viewer__picture:not(.is-1)',
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
translateX (element: HTMLElement, index: number) {
|
translateX (element: HTMLElement, index: number) {
|
||||||
const x = getComputedStyle(element).getPropertyValue('--offset-x').trim()
|
const x = getComputedStyle(element).getPropertyValue('--offset-x').trim()
|
||||||
return [`-${x}`, 0]
|
return [`-${x}`, 0]
|
||||||
},
|
},
|
||||||
delay: anime.stagger(55)
|
delay: anime.stagger(55)
|
||||||
}, 500)
|
}, 350)
|
||||||
|
|
||||||
// Prev/Next buttons
|
// Prev/Next buttons
|
||||||
timeline.add({
|
timeline.add({
|
||||||
@@ -282,7 +283,7 @@
|
|||||||
translateY: ['100%', 0],
|
translateY: ['100%', 0],
|
||||||
delay: anime.stagger(200),
|
delay: anime.stagger(200),
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
}, 700)
|
}, 1100)
|
||||||
|
|
||||||
// Transition in
|
// Transition in
|
||||||
requestAnimationFrame(timeline.play)
|
requestAnimationFrame(timeline.play)
|
||||||
@@ -320,12 +321,12 @@
|
|||||||
|
|
||||||
<div class="viewer__carousel">
|
<div class="viewer__carousel">
|
||||||
<div class="viewer__images" use:swipe on:swipe={handleSwipe} on:tap={toggleFullscreen}>
|
<div class="viewer__images" use:swipe on:swipe={handleSwipe} on:tap={toggleFullscreen}>
|
||||||
{#each visiblePhotos as photo, index (photo.id)}
|
{#each visiblePhotos as { id, image, title }, index (id)}
|
||||||
<div class="viewer__picture is-{currentIndex === 0 ? index + 1 : index}">
|
<div class="viewer__picture is-{currentIndex === 0 ? index + 1 : index}">
|
||||||
<Image
|
<Image
|
||||||
class="photo"
|
class="photo {image.width / image.height < 1.475 ? 'not-landscape' : ''}"
|
||||||
id={photo.image.id}
|
id={image.id}
|
||||||
alt={photo.title}
|
alt={title}
|
||||||
sizeKey="photo-list"
|
sizeKey="photo-list"
|
||||||
sizes={{
|
sizes={{
|
||||||
small: { width: 500 },
|
small: { width: 500 },
|
||||||
@@ -366,14 +367,20 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<span class="sep">·</span> <time datetime={dayjs(currentPhoto.date_taken).format('YYYY-MM-DD')}>{dayjs(currentPhoto.date_taken).format('MMMM YYYY')}</time>
|
{#if currentPhoto.date_taken}
|
||||||
|
<span class="sep">·</span>
|
||||||
|
<time datetime={dayjs(currentPhoto.date_taken).format('YYYY-MM-DD')}>{dayjs(currentPhoto.date_taken).format('MMMM YYYY')}</time>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if isFullscreen}
|
{#if isFullscreen}
|
||||||
<div class="viewer__fullscreen" bind:this={fullscreenEl} on:click={toggleFullscreen}>
|
<div class="viewer__fullscreen" bind:this={fullscreenEl} on:click={toggleFullscreen}
|
||||||
|
in:fade={{ easing: quartOut, duration: 1000 }}
|
||||||
|
out:fade={{ easing: quartOut, duration: 1000, delay: 300 }}
|
||||||
|
>
|
||||||
<div class="inner" transition:scale={{ easing: quartOut, start: 1.1, duration: 1000 }}>
|
<div class="inner" transition:scale={{ easing: quartOut, start: 1.1, duration: 1000 }}>
|
||||||
<Image
|
<Image
|
||||||
id={currentPhoto.image.id}
|
id={currentPhoto.image.id}
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ export async function get({ params }: RequestEvent): Promise<RequestHandlerOutpu
|
|||||||
image {
|
image {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
|
width, height
|
||||||
}
|
}
|
||||||
city
|
city
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,10 @@
|
|||||||
transform: translate3d(var(--offset-x), var(--offset-y), 0) scale(var(--scale)) rotate(var(--rotate));
|
transform: translate3d(var(--offset-x), var(--offset-y), 0) scale(var(--scale)) rotate(var(--rotate));
|
||||||
transition: opacity 1s var(--ease-quart), transform 1s var(--ease-quart);
|
transition: opacity 1s var(--ease-quart), transform 1s var(--ease-quart);
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
|
box-shadow:
|
||||||
|
0 12px 12px rgba(#000, 0.15),
|
||||||
|
0 20px 20px rgba(#000, 0.15),
|
||||||
|
0 48px 48px rgba(#000, 0.15);
|
||||||
|
|
||||||
picture {
|
picture {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -106,6 +110,12 @@
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
transition: opacity 1s var(--ease-quart);
|
transition: opacity 1s var(--ease-quart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.not-landscape {
|
||||||
|
img {
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hidden photo over
|
// Hidden photo over
|
||||||
@@ -115,6 +125,7 @@
|
|||||||
--offset-x: 0%;
|
--offset-x: 0%;
|
||||||
--offset-y: -7%;
|
--offset-y: -7%;
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
.photo {
|
.photo {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@@ -133,13 +144,6 @@
|
|||||||
--rotate: 0deg;
|
--rotate: 0deg;
|
||||||
--offset-y: 0%;
|
--offset-y: 0%;
|
||||||
|
|
||||||
.photo {
|
|
||||||
box-shadow:
|
|
||||||
0 12px 12px rgba(#000, 0.15),
|
|
||||||
0 20px 20px rgba(#000, 0.15),
|
|
||||||
0 48px 48px rgba(#000, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
@include bp (md) {
|
@include bp (md) {
|
||||||
--offset-x: 0%;
|
--offset-x: 0%;
|
||||||
--offset-y: 0%;
|
--offset-y: 0%;
|
||||||
@@ -234,7 +238,7 @@
|
|||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
color: $color-secondary;
|
color: $color-secondary;
|
||||||
font-size: clamp(#{rem(20px)}, 6.5vw, #{rem(28px)});
|
font-size: clamp(#{rem(18px)}, 5.5vw, #{rem(28px)});
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
|
|
||||||
@include bp (md) {
|
@include bp (md) {
|
||||||
@@ -246,15 +250,10 @@
|
|||||||
.detail {
|
.detail {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 24px;
|
|
||||||
color: rgba($color-tertiary, 0.7);
|
color: rgba($color-tertiary, 0.7);
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
|
||||||
@include bp (md) {
|
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
@include bp (lg) {
|
@include bp (lg) {
|
||||||
margin-top: 0;
|
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding-left: 12px;
|
padding-left: 12px;
|
||||||
@@ -375,12 +374,15 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
background: $color-primary-darker;
|
||||||
|
|
||||||
.inner {
|
.inner {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
picture {
|
picture {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@@ -395,6 +397,7 @@
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.close {
|
.close {
|
||||||
$color-shadow: rgba(#000, 0.15);
|
$color-shadow: rgba(#000, 0.15);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
Reference in New Issue
Block a user