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:
2022-06-14 23:14:12 +02:00
parent 9801fec217
commit 7d4899fa48
3 changed files with 36 additions and 25 deletions

View File

@@ -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">&middot;</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">&middot;</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}

View File

@@ -53,6 +53,7 @@ export async function get({ params }: RequestEvent): Promise<RequestHandlerOutpu
image { image {
id id
title title
width, height
} }
city city
} }

View File

@@ -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;