🐛 Setup page transitions

Bugged for some reason, the old page stays before the new page loading at the end
This commit is contained in:
2021-11-17 21:54:22 +01:00
parent 1b181b92fc
commit 8b4070aeb2
12 changed files with 140 additions and 31 deletions

View File

@@ -1,9 +1,11 @@
<script lang="ts"> <script lang="ts">
import { page } from '$app/stores' import { page } from '$app/stores'
import { getAssetUrlKey } from '$utils/helpers' import { getAssetUrlKey } from '$utils/helpers'
import { fade } from 'svelte/transition'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import advancedFormat from 'dayjs/plugin/advancedFormat.js' import advancedFormat from 'dayjs/plugin/advancedFormat.js'
import relativeTime from 'dayjs/plugin/relativeTime.js' import relativeTime from 'dayjs/plugin/relativeTime.js'
import { DURATION } from '$utils/contants'
// Components // Components
import Metas from '$components/Metas.svelte' import Metas from '$components/Metas.svelte'
import Icon from '$components/atoms/Icon.svelte' import Icon from '$components/atoms/Icon.svelte'
@@ -95,14 +97,11 @@
/> />
<main class="location-page">
<section class="location-page__intro grid" <main class="location-page"
style=" in:fade={{ duration: DURATION.PAGE_IN, delay: DURATION.PAGE_OUT }}
--illus-desktop: url({getAssetUrlKey(hasIllustration && location.illustration_desktop.id, 'illustration-desktop-1x')}); out:fade={{ duration: DURATION.PAGE_OUT }}
--illus-desktop-2x: url({getAssetUrlKey(hasIllustration && location.illustration_desktop_2x.id, 'illustration-desktop-2x')}); >
--illus-mobile: url({getAssetUrlKey(hasIllustration && location.illustration_mobile.id, 'illustration-mobile')});
"
>
<h1 class="title"> <h1 class="title">
<span class="housesof"> <span class="housesof">
<strong>Houses</strong> <strong>Houses</strong>
@@ -155,7 +154,16 @@
</div> </div>
</div> </div>
<div class="location-page__illustration" /> <div class="location-page__illustration"
style="
--illus-desktop: url({getAssetUrlKey(hasIllustration && location.illustration_desktop.id, 'illustration-desktop-1x')});
--illus-desktop-2x: url({getAssetUrlKey(hasIllustration && location.illustration_desktop_2x.id, 'illustration-desktop-2x')});
--illus-mobile: url({getAssetUrlKey(hasIllustration && location.illustration_mobile.id, 'illustration-mobile')});
--parallax-y: {illustrationOffsetY}px;
"
>
<div />
</div>
</section> </section>
{#if photos.length} {#if photos.length}
@@ -174,7 +182,7 @@
</p> </p>
</div> </div>
<figure class="house__photo"> <figure class="house__photo">
<a href="/{params.country}/{params.location}/{slug}"> <a href="/{params.country}/{params.location}/{slug}" sveltekit:prefetch sveltekit:noscroll>
<Image <Image
id={id} id={id}
sizeKey="photo-list" sizeKey="photo-list"

View File

@@ -1,7 +1,9 @@
<script lang="ts"> <script lang="ts">
import '../style/style.scss' import '../style/style.scss'
import { page } from '$app/stores' import { navigating, page } from '$app/stores'
import { setContext } from 'svelte' import { onMount, setContext } from 'svelte'
import { pageLoading } from '$utils/stores'
import { DURATION } from '$utils/contants'
import '$utils/polyfills' import '$utils/polyfills'
// Components // Components
import SVGSprite from '$components/SVGSprite.svelte' import SVGSprite from '$components/SVGSprite.svelte'
@@ -16,6 +18,32 @@
...data, ...data,
count, count,
}) })
/**
* On page change
*/
navigating.subscribe((store: any) => {
if (store) {
$pageLoading = true
// Turn page loading when changing page
setTimeout(() => {
$pageLoading = false
}, DURATION.PAGE_IN * 1.25)
// Scroll back to top between page transitions
setTimeout(() => {
// scrollToTop()
window.scrollTo(0,0)
}, DURATION.PAGE_OUT)
}
})
onMount(() => {
// Avoid FOUC
document.body.style.opacity = '1'
})
</script> </script>
<Switcher /> <Switcher />
@@ -26,6 +54,10 @@
<Footer /> <Footer />
{/if} {/if}
{#if $pageLoading}
<div class="page-loading" />
{/if}
<SVGSprite /> <SVGSprite />
<script context="module" lang="ts"> <script context="module" lang="ts">

View File

@@ -1,4 +1,6 @@
<script lang="ts"> <script lang="ts">
import { fade } from 'svelte/transition'
import { DURATION } from '$utils/contants'
// Components // Components
import Metas from '$components/Metas.svelte' import Metas from '$components/Metas.svelte'
import SiteTitle from '$components/atoms/SiteTitle.svelte' import SiteTitle from '$components/atoms/SiteTitle.svelte'
@@ -14,7 +16,10 @@
/> />
<main class="credits"> <main class="credits"
in:fade={{ duration: DURATION.PAGE_IN, delay: DURATION.PAGE_OUT }}
out:fade={{ duration: DURATION.PAGE_OUT }}
>
<section class="credits__heading"> <section class="credits__heading">
<SiteTitle variant="inline" /> <SiteTitle variant="inline" />
<p class="text-medium">{data.credits.text}</p> <p class="text-medium">{data.credits.text}</p>

View File

@@ -1,8 +1,9 @@
<script lang="ts"> <script lang="ts">
import { getContext, onMount } from 'svelte' import { getContext, onMount } from 'svelte'
import { fade } from 'svelte/transition'
import { page } from '$app/stores' import { page } from '$app/stores'
import { lerp, map } from '$utils/functions'
import anime from 'animejs' import anime from 'animejs'
import { DURATION } from '$utils/contants'
// Components // Components
import Metas from '$components/Metas.svelte' import Metas from '$components/Metas.svelte'
import SplitText from '$components/SplitText.svelte' import SplitText from '$components/SplitText.svelte'
@@ -43,9 +44,9 @@
// Reveal text // Reveal text
introTimeline.add({ introTimeline.add({
targets: '.homepage__headline', targets: '.homepage__headline',
translateY: [24, 0], translateY: [16, 0],
opacity: [0, 1], opacity: [0, 1],
}, 600) }, 900)
// Animate collage photos // Animate collage photos
introTimeline.add({ introTimeline.add({
@@ -71,7 +72,10 @@
image="" image=""
/> />
<main class="homepage"> <main class="homepage"
in:fade={{ duration: DURATION.PAGE_IN, delay: DURATION.PAGE_OUT }}
out:fade={{ duration: DURATION.PAGE_OUT }}
>
<section class="homepage__intro"> <section class="homepage__intro">
<ScrollingTitle tag="h1" class="homepage__title--houses" label="Houses of the World" parallax={introTitleParallax} offsetTop={100}> <ScrollingTitle tag="h1" class="homepage__title--houses" label="Houses of the World" parallax={introTitleParallax} offsetTop={100}>
<SplitText text="Houses" mode="chars" /> <SplitText text="Houses" mode="chars" />

View File

@@ -1,5 +1,7 @@
<script lang="ts"> <script lang="ts">
import { getContext } from 'svelte' import { getContext } from 'svelte'
import { fade } from 'svelte/transition'
import { DURATION } from '$utils/contants'
// Components // Components
import Metas from '$components/Metas.svelte' import Metas from '$components/Metas.svelte'
import InteractiveGlobe from '$components/organisms/InteractiveGlobe.svelte' import InteractiveGlobe from '$components/organisms/InteractiveGlobe.svelte'
@@ -17,7 +19,10 @@
image="" image=""
/> />
<main class="explore"> <main class="explore"
in:fade={{ duration: DURATION.PAGE_IN, delay: DURATION.PAGE_OUT }}
out:fade={{ duration: DURATION.PAGE_OUT }}
>
<Heading <Heading
text="Explore the globe to discover unique locations across the world" text="Explore the globe to discover unique locations across the world"
/> />

View File

@@ -2,12 +2,13 @@
import { page } from '$app/stores' import { page } from '$app/stores'
import { browser } from '$app/env' import { browser } from '$app/env'
import { goto } from '$app/navigation' import { goto } from '$app/navigation'
import { fly } from 'svelte/transition'
import { getContext, onMount } from 'svelte' import { getContext, onMount } from 'svelte'
import { fade, fly } from 'svelte/transition'
import { quartOut } from 'svelte/easing' import { quartOut } from 'svelte/easing'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime.js' import relativeTime from 'dayjs/plugin/relativeTime.js'
import { map, lerp, throttle } from '$utils/functions' import { map, lerp, throttle } from '$utils/functions'
import { DURATION } from '$utils/contants'
// Components // Components
import Metas from '$components/Metas.svelte' import Metas from '$components/Metas.svelte'
import SplitText from '$components/SplitText.svelte' import SplitText from '$components/SplitText.svelte'

View File

@@ -1,6 +1,8 @@
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { fade } from 'svelte/transition'
import { shopLocations, cartOpen, cartNotifications } from '$utils/stores/shop' import { shopLocations, cartOpen, cartNotifications } from '$utils/stores/shop'
import { DURATION } from '$utils/contants'
// Components // Components
import Metas from '$components/Metas.svelte' import Metas from '$components/Metas.svelte'
import SiteTitle from '$components/atoms/SiteTitle.svelte' import SiteTitle from '$components/atoms/SiteTitle.svelte'
@@ -57,7 +59,10 @@
image="" image=""
/> />
<main class="shop-page"> <main class="shop-page"
in:fade={{ duration: DURATION.PAGE_IN, delay: DURATION.PAGE_OUT }}
out:fade={{ duration: DURATION.PAGE_OUT }}
>
<Cart /> <Cart />
<section class="shop-page__intro" bind:this={introEl}> <section class="shop-page__intro" bind:this={introEl}>

View File

@@ -1,5 +1,7 @@
<script lang="ts"> <script lang="ts">
import { fade } from 'svelte/transition'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { DURATION } from '$utils/contants'
// Components // Components
import Metas from '$components/Metas.svelte' import Metas from '$components/Metas.svelte'
import Image from '$components/atoms/Image.svelte' import Image from '$components/atoms/Image.svelte'
@@ -16,7 +18,10 @@
image="" image=""
/> />
<main class="subscribe"> <main class="subscribe"
in:fade={{ duration: DURATION.PAGE_IN, delay: DURATION.PAGE_OUT }}
out:fade={{ duration: DURATION.PAGE_OUT }}
>
<Heading <Heading
text="If you wish to be pinged when new photos are added to and limited prints become available on our shop, sign up below." text="If you wish to be pinged when new photos are added to and limited prints become available on our shop, sign up below."
/> />

View File

@@ -87,3 +87,25 @@ button {
transition: opacity 0.7s var(--ease-quart), transform 0.7s var(--ease-quart); transition: opacity 0.7s var(--ease-quart), transform 0.7s var(--ease-quart);
} }
} }
// Mask for animations
.mask {
display: block;
overflow: hidden;
white-space: nowrap;
span {
display: inline-block;
}
}
// Page loading overlay
.page-loading {
position: fixed;
z-index: 2000;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: wait;
}

View File

@@ -6,7 +6,6 @@
.location-page__intro { .location-page__intro {
position: relative; position: relative;
background: $color-primary; background: $color-primary;
// padding-top: clamp(100px, 25vw, 400px);
@include bp (sm) { @include bp (sm) {
padding-top: clamp(40px, 14vw, 320px); padding-top: clamp(40px, 14vw, 320px);
@@ -154,19 +153,29 @@
position: absolute; position: absolute;
z-index: 1; z-index: 1;
top: 0; top: 0;
left: 50%; left: 0;
right: 0;
width: clamp(320px, 100vw, 2560px); width: clamp(320px, 100vw, 2560px);
height: 100%; height: 100%;
background: 0 0 var(--illus-mobile) no-repeat; margin: 0 auto;
background-size: 100% auto; overflow: hidden;
transform: translate3d(-50%, 0, 0); transform-origin: top center;
div {
width: 100%;
height: 100%;
background: 0 0 var(--illus-mobile) no-repeat;
background-size: 100% auto;
transform: translate3d(0, var(--parallax-y), 0);
transition: transform 0.7s var(--ease-quart);
will-change: transform, opacity;
@include bp (sm) { @include bp (sm) {
background-image: var(--illus-desktop); background-image: var(--illus-desktop);
} }
@include bp (xl) { @include bp (xl) {
background-image: var(--illus-desktop-2x); background-image: var(--illus-desktop-2x);
}
} }
} }

View File

@@ -0,0 +1,10 @@
// Delays
export const DELAY = {
PAGE_LOADING: 600,
}
// Durations
export const DURATION = {
PAGE_IN: 400,
PAGE_OUT: 400,
}

View File

@@ -0,0 +1,3 @@
import { writable } from 'svelte/store'
export const pageLoading = writable(false)