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 { goto } from '$app/navigation'
|
||||
import { onMount, tick } from 'svelte'
|
||||
import { scale } from 'svelte/transition'
|
||||
import { fade, scale } from 'svelte/transition'
|
||||
import { quartOut } from 'svelte/easing'
|
||||
import { getAssetUrlKey } from '$utils/helpers'
|
||||
import { fetchAPI } from '$utils/api'
|
||||
@@ -66,7 +66,7 @@
|
||||
}
|
||||
|
||||
// Define previous URL
|
||||
$: previousUrl = $previousPage ?? `/${location.country.slug}/${location.slug}`
|
||||
$: previousUrl = $previousPage ? $previousPage : `/${location.country.slug}/${location.slug}`
|
||||
|
||||
|
||||
/**
|
||||
@@ -130,7 +130,7 @@
|
||||
await tick()
|
||||
const picture = fullscreenEl.querySelector('picture')
|
||||
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({
|
||||
duration: 1600,
|
||||
easing: 'easeOutQuart',
|
||||
autoplay: false,
|
||||
})
|
||||
|
||||
anime.set('.viewer__picture', {
|
||||
@@ -238,14 +239,14 @@
|
||||
duration: 900,
|
||||
}, 250)
|
||||
timeline.add({
|
||||
targets: '.viewer__picture:not(.is-0):not(.is-1)',
|
||||
targets: '.viewer__picture:not(.is-1)',
|
||||
opacity: 1,
|
||||
translateX (element: HTMLElement, index: number) {
|
||||
const x = getComputedStyle(element).getPropertyValue('--offset-x').trim()
|
||||
return [`-${x}`, 0]
|
||||
},
|
||||
delay: anime.stagger(55)
|
||||
}, 500)
|
||||
}, 350)
|
||||
|
||||
// Prev/Next buttons
|
||||
timeline.add({
|
||||
@@ -282,7 +283,7 @@
|
||||
translateY: ['100%', 0],
|
||||
delay: anime.stagger(200),
|
||||
duration: 1000,
|
||||
}, 700)
|
||||
}, 1100)
|
||||
|
||||
// Transition in
|
||||
requestAnimationFrame(timeline.play)
|
||||
@@ -320,12 +321,12 @@
|
||||
|
||||
<div class="viewer__carousel">
|
||||
<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}">
|
||||
<Image
|
||||
class="photo"
|
||||
id={photo.image.id}
|
||||
alt={photo.title}
|
||||
class="photo {image.width / image.height < 1.475 ? 'not-landscape' : ''}"
|
||||
id={image.id}
|
||||
alt={title}
|
||||
sizeKey="photo-list"
|
||||
sizes={{
|
||||
small: { width: 500 },
|
||||
@@ -366,14 +367,20 @@
|
||||
{/if}
|
||||
</span>
|
||||
</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>
|
||||
|
||||
{#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 }}>
|
||||
<Image
|
||||
id={currentPhoto.image.id}
|
||||
|
||||
@@ -53,6 +53,7 @@ export async function get({ params }: RequestEvent): Promise<RequestHandlerOutpu
|
||||
image {
|
||||
id
|
||||
title
|
||||
width, height
|
||||
}
|
||||
city
|
||||
}
|
||||
|
||||
@@ -84,6 +84,10 @@
|
||||
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);
|
||||
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 {
|
||||
position: absolute;
|
||||
@@ -106,6 +110,12 @@
|
||||
user-select: none;
|
||||
transition: opacity 1s var(--ease-quart);
|
||||
}
|
||||
|
||||
&.not-landscape {
|
||||
img {
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hidden photo over
|
||||
@@ -115,6 +125,7 @@
|
||||
--offset-x: 0%;
|
||||
--offset-y: -7%;
|
||||
z-index: 9;
|
||||
pointer-events: none;
|
||||
|
||||
.photo {
|
||||
opacity: 0;
|
||||
@@ -133,13 +144,6 @@
|
||||
--rotate: 0deg;
|
||||
--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) {
|
||||
--offset-x: 0%;
|
||||
--offset-y: 0%;
|
||||
@@ -234,7 +238,7 @@
|
||||
|
||||
h1 {
|
||||
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;
|
||||
|
||||
@include bp (md) {
|
||||
@@ -246,15 +250,10 @@
|
||||
.detail {
|
||||
display: inline-block;
|
||||
align-items: center;
|
||||
margin-top: 24px;
|
||||
color: rgba($color-tertiary, 0.7);
|
||||
line-height: 1.5;
|
||||
|
||||
@include bp (md) {
|
||||
margin-top: 16px;
|
||||
}
|
||||
@include bp (lg) {
|
||||
margin-top: 0;
|
||||
margin-left: auto;
|
||||
text-align: right;
|
||||
padding-left: 12px;
|
||||
@@ -375,12 +374,15 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: $color-primary-darker;
|
||||
|
||||
.inner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
picture {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
@@ -395,6 +397,7 @@
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
.close {
|
||||
$color-shadow: rgba(#000, 0.15);
|
||||
position: absolute;
|
||||
|
||||
Reference in New Issue
Block a user