⚠️ Rework completely how transitions works

- Use Svelte/Sapper native if and transitions to show either the page content or the loader, then load each page animationIn
- Code is safe on SSR side, using process.browser on this if
- The <main> element is on position absolute to fade nicely the different pages
- Code cleaning
This commit is contained in:
2020-04-03 22:53:43 +02:00
parent 76e2f8242e
commit 7e0d1e33fb
21 changed files with 300 additions and 315 deletions

View File

@@ -73,14 +73,11 @@
locations,
pageReady
} from 'utils/store'
const { page } = stores()
// Components
import Transition from 'utils/Transition'
import AnalyticsTracker from 'utils/AnalyticsTracker'
// Variables
const { page } = stores()
/*
** Manipulate data
@@ -92,7 +89,9 @@
$countries.forEach(country => {
const continent = $continents.find(cont => cont.id === country.continent.id)
continent.countries = []
!continent.countries.includes(country) && continent.countries.push(country)
if (!continent.countries.includes(country)) {
continent.countries.push(country)
}
})
// Replace each location's country by the database
@@ -107,12 +106,12 @@
<link rel="canonical" href={`https://${$page.host}${$page.path}`} />
</svelte:head>
<main class="housesof" style="opacity: { $pageReady ? 1 : 0}">
<main class="housesof"
class:is-transitioning={!$pageReady}
in:fade={{ duration: 600 }}
out:fade={{ duration: 600 }}
>
<slot></slot>
</main>
{#if process.env.CONFIG.TRANSITION === 'true'}
<Transition />
{/if}
<AnalyticsTracker {stores} id={process.env.CONFIG.GA_TRACKER_ID} />

View File

@@ -5,8 +5,7 @@
site,
currentLocation,
currentPhotos,
pageReady,
pageTransition
pageReady
} from 'utils/store'
// Components
@@ -15,11 +14,11 @@
import Globe from 'molecules/InteractiveGlobe'
import Locations from 'organisms/Locations'
import Footer from 'organisms/Footer'
import Transition from 'utils/Transition'
import SocialMetas from 'utils/SocialMetas'
// Animations
import { animateIn } from 'animations/page'
pageTransition.onAnimationEnd = animateIn
// Variables
const { page } = stores()
@@ -52,25 +51,27 @@
/>
</svelte:head>
<section class="page explore">
<div class="wrap">
<div class="page__top">
<a href="/" class="button-control button-control--pink dir-left" rel="prefetch">
<IconArrow direction="left" color="#fff" class="icon" />
<IconArrow direction="left" color="#fff" class="icon" hidden="true" />
</a>
<Transition {animateIn}>
<section class="page explore">
<div class="wrap">
<div class="page__top">
<a href="/" class="button-control button-control--pink dir-left" rel="prefetch">
<IconArrow direction="left" color="#fff" class="icon" />
<IconArrow direction="left" color="#fff" class="icon" hidden="true" />
</a>
<TitleSite />
<TitleSite />
</div>
<div class="page__description page__part style-description">
<p>{$site.explore_globe}</p>
</div>
</div>
<div class="page__description page__part style-description">
<p>{$site.explore_globe}</p>
</div>
</div>
<Globe />
<Globe />
<Locations />
</section>
<Locations />
</section>
<Footer />
<Footer />
</Transition>

View File

@@ -1,7 +1,7 @@
<script>
import { onMount } from 'svelte'
import { stores } from '@sapper/app'
import { site, pageReady, pageTransition } from 'utils/store'
import { site, pageReady } from 'utils/store'
// Components
import IconArrow from 'atoms/IconArrow'
@@ -10,10 +10,10 @@
import InteractiveGlobe from 'molecules/InteractiveGlobe'
import Footer from 'organisms/Footer'
import SocialMetas from 'utils/SocialMetas'
import Transition from 'utils/Transition'
// Animations
import { animateIn } from 'animations/page'
pageTransition.onAnimationEnd = animateIn
// Variables
const { page } = stores()
@@ -39,45 +39,47 @@
/>
</svelte:head>
<section class="page">
<div class="wrap">
<div class="page__top page__part">
<a href="/" class="button-control button-control--pink dir-left">
<IconArrow direction="left" color="#fff" class="icon" />
<IconArrow direction="left" color="#fff" class="icon" hidden="true" />
</a>
<Transition>
<section class="page">
<div class="wrap">
<div class="page__top page__part">
<a href="/" class="button-control button-control--pink dir-left">
<IconArrow direction="left" color="#fff" class="icon" />
<IconArrow direction="left" color="#fff" class="icon" hidden="true" />
</a>
<TitleSite />
</div>
<TitleSite />
</div>
<div class="page__description page__part style-description">
<p>{$site.credits_text}</p>
</div>
<div class="page__description page__part style-description">
<p>{$site.credits_text}</p>
</div>
{#if $site.credits_list}
<div class="page__list page__part">
{#each $site.credits_list as { title, credits }}
<div class="page__category">
<h2 class="title-category">{title}</h2>
{#each credits as { name, role, website }, i}
<dl>
<dt class="style-location">
{#if website}
<LinkTranslate href={website} text={name} target="_blank" rel="noopener" />
{:else}
{name}
{/if}
</dt>
<dd class="style-caps style-caps style-caps--transparent">{role}</dd>
</dl>
{#if $site.credits_list}
<div class="page__list page__part">
{#each $site.credits_list as { title, credits }}
<div class="page__category">
<h2 class="title-category">{title}</h2>
{#each credits as { name, role, website }, i}
<dl>
<dt class="style-location">
{#if website}
<LinkTranslate href={website} text={name} target="_blank" rel="noopener" />
{:else}
{name}
{/if}
</dt>
<dd class="style-caps style-caps style-caps--transparent">{role}</dd>
</dl>
{/each}
</div>
{/each}
</div>
{/each}
{/if}
</div>
{/if}
</div>
<InteractiveGlobe type="part" />
<InteractiveGlobe type="part" />
<Footer />
</section>
<Footer />
</section>
</Transition>

View File

@@ -31,8 +31,7 @@
site,
currentLocation,
currentPhotos,
pageReady,
pageTransition
pageReady
} from 'utils/store'
import { charsToSpan } from 'utils/functions'
@@ -53,7 +52,6 @@
// Animations
import { animateIn } from 'animations/index'
pageTransition.onAnimationEnd = animateIn
// Props and variables
export let photos = ''
@@ -86,53 +84,55 @@
/>
</svelte:head>
<section class="intro">
<div class="anim-mask">
<div class="anim title-parallax" id="title-houses">
<h1 class="title-massive" aria-label="Houses">
{@html charsToSpan('Houses')}
<Transition animateIn={animateIn}>
<section class="intro">
<div class="anim-mask">
<div class="anim title-parallax" id="title-houses">
<h1 class="title-massive" aria-label="Houses">
{@html charsToSpan('Houses')}
</h1>
</div>
</div>
<div class="wrap" id="intro-description">
<div class="intro__description style-description">
<p>{$site.description}</p>
<Button type="a" href="#choose" class="button" text="Explore locations">
<IconGlobeSmall width="22" color="#666" />
</Button>
</div>
</div>
<div id="intro-carousel">
{#if photos}
<Carousel {photos} />
<Fullscreen />
{/if}
</div>
</section>
<section class="explore explore--homepage">
<div class="of" id="title-of" aria-label="of">
<div class="anim-mask">
{@html charsToSpan('of')}
</div>
</div>
<div class="explore__description style-description" id="choose">
<p>{$site.explore_globe}</p>
</div>
<InteractiveGlobe />
<div class="anim-mask anim-title">
<h1 class="title-massive title-parallax" id="title-world" aria-label="World">
{@html charsToSpan('World')}
</h1>
</div>
</div>
<div class="wrap" id="intro-description">
<div class="intro__description style-description">
<p>{$site.description}</p>
<Locations />
</section>
<Button type="a" href="#choose" class="button" text="Explore locations">
<IconGlobeSmall width="22" color="#666" />
</Button>
</div>
</div>
<div id="intro-carousel">
{#if photos}
<Carousel {photos} />
<Fullscreen />
{/if}
</div>
</section>
<section class="explore explore--homepage">
<div class="of" id="title-of" aria-label="of">
<div class="anim-mask">
{@html charsToSpan('of')}
</div>
</div>
<div class="explore__description style-description" id="choose">
<p>{$site.explore_globe}</p>
</div>
<InteractiveGlobe />
<div class="anim-mask anim-title">
<h1 class="title-massive title-parallax" id="title-world" aria-label="World">
{@html charsToSpan('World')}
</h1>
</div>
<Locations />
</section>
<Footer />
<Footer />
</Transition>

View File

@@ -29,8 +29,7 @@
locations,
currentLocation,
currentPhotos,
pageReady,
pageTransition
pageReady
} from 'utils/store'
import { formatDate, relativeTime, getThumbnail } from 'utils/functions'
@@ -47,10 +46,10 @@
import Pagination from 'organisms/Pagination'
import Footer from 'organisms/Footer'
import SocialMetas from 'utils/SocialMetas'
import Transition from 'utils/Transition'
// Animations
import { animateIn } from 'animations/place'
pageTransition.onAnimationEnd = animateIn
// Props and variables
export let photos
@@ -108,99 +107,100 @@
/>
</svelte:head>
<Transition {animateIn}>
<section class="place">
<div class="place__title">
<h1 class="title-location title-location--big" aria-label="Houses of {location.name}">
<span class="place__title_top anim-mask">
<span class="place__title_houses">Houses</span>
<em class="place__title_of">of</em>
</span>
<span class="place__title_bottom anim-mask">
<span class="place__title_name">{location.name}</span>
</span>
</h1>
<section class="place">
<div class="place__title">
<h1 class="title-location title-location--big" aria-label="Houses of {location.name}">
<span class="place__title_top anim-mask">
<span class="place__title_houses">Houses</span>
<em class="place__title_of">of</em>
</span>
<span class="place__title_bottom anim-mask">
<span class="place__title_name">{location.name}</span>
</span>
</h1>
<a href="/choose" class="button-control button-control--big button-control--dashed" aria-label="Change the location">
<span class="center">
<IconGlobe width="44" color="#fff" />
<span>Change</span>
</span>
<svg>
<circle cx="50%" cy="50%" r="43%" />
</svg>
</a>
</div>
<a href="/choose" class="button-control button-control--big button-control--dashed" aria-label="Change the location" sapper-noscroll>
<span class="center">
<IconGlobe width="44" color="#fff" />
<span>Change</span>
</span>
<svg>
<circle cx="50%" cy="50%" r="43%" />
</svg>
</a>
</div>
<div class="place__wrap wrap">
<div class="place__description">
<div class="wrapper">
<p>{$site.description}</p>
<div class="place__wrap wrap">
<div class="place__description">
<div class="wrapper">
<p>{$site.description}</p>
{#if description}
<p>
Houses Of
<LinkChange href="/choose" text={location.name}>
<IconGlobeSmall width="14" color="#999" />
</LinkChange>
{description}
</p>
{/if}
{#if description}
<p>
Houses Of
<LinkChange href="/choose" text={location.name} noScroll="true">
<IconGlobeSmall width="14" color="#999" />
</LinkChange>
{description}
</p>
{/if}
{#if photos}
<p class="updated style-caps">
<strong>Updated</strong>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
</p>
<ToggleLayout />
{/if}
</div>
</div>
</div>
{#if illustration_desktop && illustration_mobile}
<div class="place__illustration"
style="--url-desktop: url({illustration_desktop.full_url}); --url-mobile: url({illustration_mobile.full_url});"
/>
{/if}
</section>
<section class="photos photos--{layoutSetting || 'list'}">
<div class="photos__sidewrap wrap">
<aside class="photos__side">
<Switcher type="switcher--side" />
{#if photos}
<p class="updated style-caps">
<strong>Updated</strong>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
</p>
<ToggleLayout />
{/if}
</div>
</aside>
</div>
</div>
{#if illustration_desktop && illustration_mobile}
<div class="place__illustration"
style="--url-desktop: url({illustration_desktop.full_url}); --url-mobile: url({illustration_mobile.full_url});"
/>
{/if}
</section>
{#if photos}
<div class="photos__view wrap">
{#each paginatedPhotos as photo, index}
<Photo
photo={photo}
index={photos.length - photos.indexOf(photo)}
layout={layoutSetting}
/>
{/each}
</div>
<section class="photos photos--{layoutSetting || 'list'}">
<div class="photos__sidewrap wrap">
<aside class="photos__side">
<Switcher type="switcher--side" />
{#if photos}
<p class="updated style-caps">
<strong>Updated</strong>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
</p>
{/if}
</aside>
</div>
{#if photos}
<div class="photos__view wrap">
{#each paginatedPhotos as photo, index}
<Photo
photo={photo}
index={photos.length - photos.indexOf(photo)}
layout={layoutSetting}
<Pagination
{photos} {paginatedPhotos} {photosPerPage}
on:updatePagination={updatePagination}
/>
{/each}
</div>
<Pagination
{photos} {paginatedPhotos} {photosPerPage}
on:updatePagination={updatePagination}
/>
{:else}
<div class="wrap" style="padding-top: 20vw; padding-bottom: 20vw;">
<p style="text-align: center; color: #333;">No photo for {location.name}</p>
</div>
{/if}
</section>
{:else}
<div class="wrap" style="padding-top: 20vw; padding-bottom: 20vw;">
<p style="text-align: center; color: #333;">No photo for {location.name}</p>
</div>
{/if}
</section>
<Footer />
<Footer />
</Transition>

View File

@@ -35,8 +35,7 @@
locations,
currentLocation,
currentPhotos,
pageReady,
pageTransition
pageReady
} from 'utils/store'
import { getThumbnail } from 'utils/functions'
@@ -45,11 +44,11 @@
import IconCross from 'atoms/IconCross'
import Carousel from 'organisms/Carousel'
import Fullscreen from 'organisms/Fullscreen'
import Transition from 'utils/Transition'
import SocialMetas from 'utils/SocialMetas'
// Animations
import { animateIn } from 'animations/viewer'
pageTransition.onAnimationEnd = animateIn
// Props
export let photos
@@ -100,30 +99,32 @@
<svelte:window bind:innerWidth={windowWidth} />
<section class="viewer">
<div class="viewer__top">
<p class="tip">Tap for fullscreen</p>
<Transition {animateIn}>
<section class="viewer">
<div class="viewer__top">
<p class="tip">Tap for fullscreen</p>
<div class="viewer__buttons">
<a href="/choose" class="button-control button-control--dashed" aria-label="Change the location" rel="prefetch">
<IconGlobe color="#fff" width={windowWidth >= 768 ? 22 : 18} />
<svg>
<circle cx="50%" cy="50%" r="{windowWidth >= 768 ? 32 : 24}px"></circle>
</svg>
</a>
<a href="/location/{$currentLocation.country.slug}/{$currentLocation.slug}" class="button-control button-control--pink dir-bottom" aria-label="Back to photos" rel="prefetch">
<IconCross color="#fff" width="18" class="icon" />
<IconCross color="#fff" width="18" class="icon" hidden="true" />
</a>
<div class="viewer__buttons">
<a href="/choose" class="button-control button-control--dashed" aria-label="Change the location" rel="prefetch">
<IconGlobe color="#fff" width={windowWidth >= 768 ? 22 : 18} />
<svg>
<circle cx="50%" cy="50%" r="{windowWidth >= 768 ? 32 : 24}px"></circle>
</svg>
</a>
<a href="/location/{$currentLocation.country.slug}/{$currentLocation.slug}" class="button-control button-control--pink dir-bottom" aria-label="Back to photos" rel="prefetch">
<IconCross color="#fff" width="18" class="icon" />
<IconCross color="#fff" width="18" class="icon" hidden="true" />
</a>
</div>
<a href="/" bind:this={gotoLink} aria-hidden="true" hidden class="hidden">&nbsp;</a>
</div>
<a href="/" bind:this={gotoLink} aria-hidden="true" hidden class="hidden" sapper-noscroll>&nbsp;</a>
</div>
<Carousel
viewer="true"
photos={photos}
on:photoChange={photoChanged}
/>
<Carousel
viewer="true"
photos={photos}
on:photoChange={photoChanged}
/>
<Fullscreen />
</section>
<Fullscreen />
</section>
</Transition>