refactor: use global page transition in main layout
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
import { PUBLIC_LIST_INCREMENT } from '$env/static/public'
|
||||
// Components
|
||||
import Metas from '$components/Metas.svelte'
|
||||
import PageTransition from '$components/PageTransition.svelte'
|
||||
import Image from '$components/atoms/Image.svelte'
|
||||
import Button from '$components/atoms/Button.svelte'
|
||||
import IconEarth from '$components/atoms/IconEarth.svelte'
|
||||
@@ -218,149 +217,147 @@
|
||||
/>
|
||||
|
||||
|
||||
<PageTransition>
|
||||
<main class="location-page">
|
||||
<section class="location-page__intro grid" bind:this={introEl}>
|
||||
<h1 class="title" class:is-short={location.name.length <= 4}>
|
||||
<span class="housesof mask">
|
||||
<strong class="word">Houses</strong>
|
||||
<span class="of">of</span>
|
||||
</span>
|
||||
<strong class="city mask">
|
||||
<span class="word">{location.name}</span>
|
||||
</strong>
|
||||
</h1>
|
||||
<main class="location-page">
|
||||
<section class="location-page__intro grid" bind:this={introEl}>
|
||||
<h1 class="title" class:is-short={location.name.length <= 4}>
|
||||
<span class="housesof mask">
|
||||
<strong class="word">Houses</strong>
|
||||
<span class="of">of</span>
|
||||
</span>
|
||||
<strong class="city mask">
|
||||
<span class="word">{location.name}</span>
|
||||
</strong>
|
||||
</h1>
|
||||
|
||||
<div class="location-page__description grid">
|
||||
<div class="wrap">
|
||||
<div class="text-medium">
|
||||
Houses of {location.name} {location.description ?? 'has no description yet'}
|
||||
</div>
|
||||
<div class="info">
|
||||
<p class="text-label">
|
||||
Photos by
|
||||
{#each location.credits as { credit_id: { name, website } }}
|
||||
{#if website}
|
||||
<a href={website} target="_blank" rel="noopener external">
|
||||
{name}
|
||||
</a>
|
||||
{:else}
|
||||
<span>{name}</span>
|
||||
{/if}
|
||||
{/each}
|
||||
<div class="location-page__description grid">
|
||||
<div class="wrap">
|
||||
<div class="text-medium">
|
||||
Houses of {location.name} {location.description ?? 'has no description yet'}
|
||||
</div>
|
||||
<div class="info">
|
||||
<p class="text-label">
|
||||
Photos by
|
||||
{#each location.credits as { credit_id: { name, website } }}
|
||||
{#if website}
|
||||
<a href={website} target="_blank" rel="noopener external">
|
||||
{name}
|
||||
</a>
|
||||
{:else}
|
||||
<span>{name}</span>
|
||||
{/if}
|
||||
{/each}
|
||||
</p>
|
||||
{#if latestPhoto}
|
||||
·
|
||||
<p class="text-label" title={dayjs(latestPhoto.date_created).format('DD/MM/YYYY, hh:mm')}>
|
||||
Updated <time datetime={dayjs(latestPhoto.date_created).format('YYYY-MM-DD')}>
|
||||
{dayjs().to(dayjs(latestPhoto.date_created))}
|
||||
</time>
|
||||
</p>
|
||||
{#if latestPhoto}
|
||||
·
|
||||
<p class="text-label" title={dayjs(latestPhoto.date_created).format('DD/MM/YYYY, hh:mm')}>
|
||||
Updated <time datetime={dayjs(latestPhoto.date_created).format('YYYY-MM-DD')}>
|
||||
{dayjs().to(dayjs(latestPhoto.date_created))}
|
||||
</time>
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="ctas">
|
||||
<Button url="/locations" text="Change location" class="shadow-small">
|
||||
<IconEarth />
|
||||
<div class="ctas">
|
||||
<Button url="/locations" text="Change location" class="shadow-small">
|
||||
<IconEarth />
|
||||
</Button>
|
||||
|
||||
{#if location.has_poster}
|
||||
<Button url="/shop/poster-{location.slug}" text="Buy the poster" color="pinklight" class="shadow-small">
|
||||
<!-- <IconEarth /> -->
|
||||
</Button>
|
||||
|
||||
{#if location.has_poster}
|
||||
<Button url="/shop/poster-{location.slug}" text="Buy the poster" color="pinklight" class="shadow-small">
|
||||
<!-- <IconEarth /> -->
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if hasIllustration}
|
||||
<picture class="location-page__illustration" style:--parallax-y="{illustrationOffsetY}px">
|
||||
<source media="(min-width: 1200px)" srcset={getAssetUrlKey(location.illustration_desktop_2x.id, 'illustration-desktop-2x')}>
|
||||
<source media="(min-width: 768px)" srcset={getAssetUrlKey(location.illustration_desktop.id, 'illustration-desktop-1x')}>
|
||||
<img
|
||||
src={getAssetUrlKey(location.illustration_mobile.id, 'illustration-mobile')}
|
||||
width={320}
|
||||
height={824}
|
||||
alt="Illustration for {location.name}"
|
||||
decoding="async"
|
||||
/>
|
||||
</picture>
|
||||
{/if}
|
||||
{#if hasIllustration}
|
||||
<picture class="location-page__illustration" style:--parallax-y="{illustrationOffsetY}px">
|
||||
<source media="(min-width: 1200px)" srcset={getAssetUrlKey(location.illustration_desktop_2x.id, 'illustration-desktop-2x')}>
|
||||
<source media="(min-width: 768px)" srcset={getAssetUrlKey(location.illustration_desktop.id, 'illustration-desktop-1x')}>
|
||||
<img
|
||||
src={getAssetUrlKey(location.illustration_mobile.id, 'illustration-mobile')}
|
||||
width={320}
|
||||
height={824}
|
||||
alt="Illustration for {location.name}"
|
||||
decoding="async"
|
||||
/>
|
||||
</picture>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
{#if photos.length}
|
||||
<section class="location-page__houses" bind:this={photosListEl} data-sveltekit-noscroll>
|
||||
{#each photos as { title, image: { id, title: alt, width, height }, slug, city, date_taken }, index}
|
||||
<House
|
||||
{title}
|
||||
photoId={id}
|
||||
photoAlt={alt}
|
||||
url="/{params.country}/{params.location}/{slug}"
|
||||
{city}
|
||||
location={location.name}
|
||||
ratio={width / height}
|
||||
date={date_taken}
|
||||
index="{(totalPhotos - index < 10) ? '0' : ''}{totalPhotos - index}"
|
||||
/>
|
||||
{/each}
|
||||
</section>
|
||||
|
||||
{#if photos.length}
|
||||
<section class="location-page__houses" bind:this={photosListEl} data-sveltekit-noscroll>
|
||||
{#each photos as { title, image: { id, title: alt, width, height }, slug, city, date_taken }, index}
|
||||
<House
|
||||
{title}
|
||||
photoId={id}
|
||||
photoAlt={alt}
|
||||
url="/{params.country}/{params.location}/{slug}"
|
||||
{city}
|
||||
location={location.name}
|
||||
ratio={width / height}
|
||||
date={date_taken}
|
||||
index="{(totalPhotos - index < 10) ? '0' : ''}{totalPhotos - index}"
|
||||
/>
|
||||
{/each}
|
||||
</section>
|
||||
<section class="location-page__next container">
|
||||
<Pagination
|
||||
ended={ended}
|
||||
current={currentPhotosAmount}
|
||||
total={totalPhotos}
|
||||
on:click={() => !ended && loadMorePhotos()}
|
||||
>
|
||||
{#if !ended}
|
||||
<p class="more">See more photos</p>
|
||||
{:else}
|
||||
<p>You've seen it all!</p>
|
||||
{/if}
|
||||
</Pagination>
|
||||
|
||||
<section class="location-page__next container">
|
||||
<Pagination
|
||||
ended={ended}
|
||||
current={currentPhotosAmount}
|
||||
total={totalPhotos}
|
||||
on:click={() => !ended && loadMorePhotos()}
|
||||
>
|
||||
{#if !ended}
|
||||
<p class="more">See more photos</p>
|
||||
{:else}
|
||||
<p>You've seen it all!</p>
|
||||
{/if}
|
||||
</Pagination>
|
||||
|
||||
{#if ended}
|
||||
<div class="grid-modules">
|
||||
<div class="container grid">
|
||||
<div class="wrap">
|
||||
{#if location.has_poster}
|
||||
<ShopModule
|
||||
title="Poster available"
|
||||
text="Houses of {location.name} is available as a poster on our shop."
|
||||
images={product.photos_product}
|
||||
textBottom={null}
|
||||
buttonText="Buy"
|
||||
url="/shop/poster-{location.slug}"
|
||||
/>
|
||||
{:else}
|
||||
<ShopModule />
|
||||
{/if}
|
||||
<NewsletterModule theme="light" />
|
||||
</div>
|
||||
{#if ended}
|
||||
<div class="grid-modules">
|
||||
<div class="container grid">
|
||||
<div class="wrap">
|
||||
{#if location.has_poster}
|
||||
<ShopModule
|
||||
title="Poster available"
|
||||
text="Houses of {location.name} is available as a poster on our shop."
|
||||
images={product.photos_product}
|
||||
textBottom={null}
|
||||
buttonText="Buy"
|
||||
url="/shop/poster-{location.slug}"
|
||||
/>
|
||||
{:else}
|
||||
<ShopModule />
|
||||
{/if}
|
||||
<NewsletterModule theme="light" />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if location.acknowledgement}
|
||||
<div class="acknowledgement">
|
||||
<Image
|
||||
class="flag"
|
||||
id={location.country.flag.id}
|
||||
sizeKey="square-small"
|
||||
width={32} height={32}
|
||||
alt="Flag of {location.country.name}"
|
||||
/>
|
||||
<p>{location.acknowledgement}</p>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
{:else}
|
||||
<div class="location-page__message">
|
||||
<p>
|
||||
No photos available for {location.name}.<br>
|
||||
Come back later!
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
</PageTransition>
|
||||
{#if location.acknowledgement}
|
||||
<div class="acknowledgement">
|
||||
<Image
|
||||
class="flag"
|
||||
id={location.country.flag.id}
|
||||
sizeKey="square-small"
|
||||
width={32} height={32}
|
||||
alt="Flag of {location.country.name}"
|
||||
/>
|
||||
<p>{location.acknowledgement}</p>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
{:else}
|
||||
<div class="location-page__message">
|
||||
<p>
|
||||
No photos available for {location.name}.<br>
|
||||
Come back later!
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
// Components
|
||||
import Metas from '$components/Metas.svelte'
|
||||
import SplitText from '$components/SplitText.svelte'
|
||||
import PageTransition from '$components/PageTransition.svelte'
|
||||
import Image from '$components/atoms/Image.svelte'
|
||||
import Icon from '$components/atoms/Icon.svelte'
|
||||
import IconArrow from '$components/atoms/IconArrow.svelte'
|
||||
@@ -301,105 +300,103 @@
|
||||
{/if}
|
||||
|
||||
|
||||
<PageTransition>
|
||||
<main class="photo-page">
|
||||
<div class="container grid">
|
||||
<p class="photo-page__notice text-label">Tap for fullscreen</p>
|
||||
<main class="photo-page">
|
||||
<div class="container grid">
|
||||
<p class="photo-page__notice text-label">Tap for fullscreen</p>
|
||||
|
||||
<ButtonCircle
|
||||
tag="a"
|
||||
url={previousUrl}
|
||||
color="purple"
|
||||
class="close shadow-box-dark"
|
||||
label="Close"
|
||||
<ButtonCircle
|
||||
tag="a"
|
||||
url={previousUrl}
|
||||
color="purple"
|
||||
class="close shadow-box-dark"
|
||||
label="Close"
|
||||
>
|
||||
<svg width="12" height="12">
|
||||
<use xlink:href="#cross">
|
||||
</svg>
|
||||
</ButtonCircle>
|
||||
|
||||
<div class="photo-page__carousel">
|
||||
<div class="photo-page__images"
|
||||
use:swipe
|
||||
on:swipe={handleSwipe}
|
||||
on:tap={toggleFullscreen}
|
||||
>
|
||||
<svg width="12" height="12">
|
||||
<use xlink:href="#cross">
|
||||
</svg>
|
||||
</ButtonCircle>
|
||||
|
||||
<div class="photo-page__carousel">
|
||||
<div class="photo-page__images"
|
||||
use:swipe
|
||||
on:swipe={handleSwipe}
|
||||
on:tap={toggleFullscreen}
|
||||
>
|
||||
{#each visiblePhotos as { id, image, title }, index (id)}
|
||||
<div class="photo-page__picture is-{currentIndex === 0 ? index + 1 : index}">
|
||||
<Image
|
||||
class="photo {image.width / image.height < 1.475 ? 'not-landscape' : ''}"
|
||||
id={image.id}
|
||||
alt={title}
|
||||
sizeKey="photo-list"
|
||||
sizes={{
|
||||
small: { width: 500 },
|
||||
medium: { width: 850 },
|
||||
large: { width: 1280 },
|
||||
}}
|
||||
ratio={1.5}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
<div class="photo-page__controls">
|
||||
<ButtonCircle class="prev shadow-box-dark" label="Previous" disabled={!canGoNext} clone={true} on:click={goToPrevious}>
|
||||
<IconArrow color="pink" flip={true} />
|
||||
</ButtonCircle>
|
||||
<ButtonCircle class="next shadow-box-dark" label="Next" disabled={!canGoPrev} clone={true} on:click={goToNext}>
|
||||
<IconArrow color="pink" />
|
||||
</ButtonCircle>
|
||||
{#each visiblePhotos as { id, image, title }, index (id)}
|
||||
<div class="photo-page__picture is-{currentIndex === 0 ? index + 1 : index}">
|
||||
<Image
|
||||
class="photo {image.width / image.height < 1.475 ? 'not-landscape' : ''}"
|
||||
id={image.id}
|
||||
alt={title}
|
||||
sizeKey="photo-list"
|
||||
sizes={{
|
||||
small: { width: 500 },
|
||||
medium: { width: 850 },
|
||||
large: { width: 1280 },
|
||||
}}
|
||||
ratio={1.5}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
|
||||
<div class="photo-page__index title-index">
|
||||
<SplitText text="{(currentPhotoIndex < 10) ? '0' : ''}{currentPhotoIndex}" mode="chars" />
|
||||
</div>
|
||||
<div class="photo-page__controls">
|
||||
<ButtonCircle class="prev shadow-box-dark" label="Previous" disabled={!canGoNext} clone={true} on:click={goToPrevious}>
|
||||
<IconArrow color="pink" flip={true} />
|
||||
</ButtonCircle>
|
||||
<ButtonCircle class="next shadow-box-dark" label="Next" disabled={!canGoPrev} clone={true} on:click={goToNext}>
|
||||
<IconArrow color="pink" />
|
||||
</ButtonCircle>
|
||||
</div>
|
||||
|
||||
<div class="photo-page__info">
|
||||
<h1 class="title-medium">{currentPhoto.title}</h1>
|
||||
|
||||
<div class="detail text-info">
|
||||
<a href="/{location.country.slug}/{location.slug}" data-sveltekit-noscroll>
|
||||
<Icon class="icon" icon="map-pin" label="Map pin" />
|
||||
<span>
|
||||
{#if currentPhoto.city}
|
||||
{currentPhoto.city}, {location.name}, {location.country.name}
|
||||
{:else}
|
||||
{location.name}, {location.country.name}
|
||||
{/if}
|
||||
</span>
|
||||
</a>
|
||||
{#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 class="photo-page__index title-index">
|
||||
<SplitText text="{(currentPhotoIndex < 10) ? '0' : ''}{currentPhotoIndex}" mode="chars" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="photo-page__info">
|
||||
<h1 class="title-medium">{currentPhoto.title}</h1>
|
||||
|
||||
<div class="detail text-info">
|
||||
<a href="/{location.country.slug}/{location.slug}" data-sveltekit-noscroll>
|
||||
<Icon class="icon" icon="map-pin" label="Map pin" />
|
||||
<span>
|
||||
{#if currentPhoto.city}
|
||||
{currentPhoto.city}, {location.name}, {location.country.name}
|
||||
{:else}
|
||||
{location.name}, {location.country.name}
|
||||
{/if}
|
||||
</span>
|
||||
</a>
|
||||
{#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="photo-page__fullscreen" bind:this={fullscreenEl}
|
||||
on:click={toggleFullscreen} on:keydown
|
||||
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}
|
||||
sizeKey="photo-grid-large"
|
||||
width={1266}
|
||||
height={844}
|
||||
alt={currentPhoto.title}
|
||||
/>
|
||||
<ButtonCircle color="gray-medium" class="close">
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="#fff" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.751 0c4.274 0 7.752 3.477 7.752 7.751 0 1.846-.65 3.543-1.73 4.875l3.99 3.991a.81.81 0 1 1-1.146 1.146l-3.99-3.991a7.714 7.714 0 0 1-4.876 1.73C3.477 15.503 0 12.027 0 7.753 0 3.476 3.477 0 7.751 0Zm0 1.62a6.138 6.138 0 0 0-6.13 6.131 6.138 6.138 0 0 0 6.13 6.132 6.138 6.138 0 0 0 6.131-6.132c0-3.38-2.75-6.13-6.13-6.13Zm2.38 5.321a.81.81 0 1 1 0 1.62h-4.76a.81.81 0 1 1 0-1.62h4.76Z" />
|
||||
</svg>
|
||||
</ButtonCircle>
|
||||
</div>
|
||||
{#if isFullscreen}
|
||||
<div class="photo-page__fullscreen" bind:this={fullscreenEl}
|
||||
on:click={toggleFullscreen} on:keydown
|
||||
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}
|
||||
sizeKey="photo-grid-large"
|
||||
width={1266}
|
||||
height={844}
|
||||
alt={currentPhoto.title}
|
||||
/>
|
||||
<ButtonCircle color="gray-medium" class="close">
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="#fff" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.751 0c4.274 0 7.752 3.477 7.752 7.751 0 1.846-.65 3.543-1.73 4.875l3.99 3.991a.81.81 0 1 1-1.146 1.146l-3.99-3.991a7.714 7.714 0 0 1-4.876 1.73C3.477 15.503 0 12.027 0 7.753 0 3.476 3.477 0 7.751 0Zm0 1.62a6.138 6.138 0 0 0-6.13 6.131 6.138 6.138 0 0 0 6.13 6.132 6.138 6.138 0 0 0 6.131-6.132c0-3.38-2.75-6.13-6.13-6.13Zm2.38 5.321a.81.81 0 1 1 0 1.62h-4.76a.81.81 0 1 1 0-1.62h4.76Z" />
|
||||
</svg>
|
||||
</ButtonCircle>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
</PageTransition>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user