183 lines
5.1 KiB
Svelte
183 lines
5.1 KiB
Svelte
<script lang="ts">
|
|
import { page } from '$app/stores'
|
|
import { getContext, onMount } from 'svelte'
|
|
import anime from 'animejs'
|
|
import type { AnimeTimelineInstance } from 'animejs'
|
|
import { DELAY } from '$utils/contants'
|
|
import { sleep } from '$utils/functions'
|
|
import { reveal, fade as animeFade } from '$animations/index'
|
|
// Components
|
|
import Metas from '$components/Metas.svelte'
|
|
import PageTransition from '$components/PageTransition.svelte'
|
|
import SplitText from '$components/SplitText.svelte'
|
|
import Button from '$components/atoms/Button.svelte'
|
|
import IconEarth from '$components/atoms/IconEarth.svelte'
|
|
import ScrollingTitle from '$components/atoms/ScrollingTitle.svelte'
|
|
import BoxCTA from '$components/atoms/BoxCTA.svelte'
|
|
import DiscoverText from '$components/atoms/DiscoverText.svelte'
|
|
import InteractiveGlobe from '$components/organisms/InteractiveGlobe.svelte'
|
|
import Collage from '$components/organisms/Collage.svelte'
|
|
import Locations from '$components/organisms/Locations.svelte'
|
|
import Shop from '$components/organisms/Shop.svelte'
|
|
import Newsletter from '$components/organisms/Newsletter.svelte'
|
|
|
|
export let photos: any
|
|
|
|
const { settings, locations }: any = getContext('global')
|
|
|
|
let scrollY: number, innerHeight: number
|
|
let timeline: AnimeTimelineInstance
|
|
|
|
|
|
onMount(() => {
|
|
timeline = anime.timeline({
|
|
duration: 1600,
|
|
easing: 'easeOutQuart',
|
|
autoplay: false,
|
|
})
|
|
|
|
// Reveal text
|
|
timeline.add({
|
|
targets: '.homepage__headline',
|
|
translateY: [16, 0],
|
|
opacity: [0, 1],
|
|
}, 750)
|
|
|
|
// Animate collage photos
|
|
timeline.add({
|
|
targets: '.collage .photo-card',
|
|
translateY: ['33.33%', 0],
|
|
rotate (item: HTMLElement) {
|
|
return [-4, getComputedStyle(item).getPropertyValue('--rotation')]
|
|
},
|
|
opacity: [0, 1],
|
|
duration: 1200,
|
|
delay: anime.stagger(75),
|
|
}, 0)
|
|
|
|
sleep(DELAY.PAGE_LOADING).then(timeline.play)
|
|
})
|
|
</script>
|
|
|
|
<svelte:window bind:scrollY bind:innerHeight />
|
|
|
|
<Metas
|
|
title="Houses Of"
|
|
description=""
|
|
image=""
|
|
/>
|
|
|
|
<PageTransition name="homepage">
|
|
<section class="homepage__intro"
|
|
use:reveal={{
|
|
animation: animeFade,
|
|
options: {
|
|
duration: 1000,
|
|
},
|
|
}}
|
|
>
|
|
<ScrollingTitle
|
|
tag="h1"
|
|
class="homepage__title--houses"
|
|
label="Houses of the World"
|
|
offsetStart={-300}
|
|
offsetEnd={400}
|
|
>
|
|
<SplitText text="Houses" mode="chars" />
|
|
</ScrollingTitle>
|
|
|
|
<div class="homepage__headline">
|
|
<p class="text-medium">
|
|
{settings.description}
|
|
</p>
|
|
|
|
<Button text="Explore locations" url="#locations">
|
|
<IconEarth animate={true} />
|
|
</Button>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="homepage__photos">
|
|
<Collage {photos} />
|
|
</section>
|
|
|
|
<div class="homepage__ctas" id="ctas">
|
|
<DiscoverText />
|
|
|
|
<div class="cards">
|
|
<BoxCTA
|
|
url="{$page.url.pathname}#locations"
|
|
icon="globe"
|
|
label="Discover locations"
|
|
alt="Globe"
|
|
/>
|
|
<BoxCTA
|
|
url="/photos"
|
|
icon="photos"
|
|
label="Browse all photos"
|
|
alt="Photos"
|
|
/>
|
|
<BoxCTA
|
|
url="/shop"
|
|
icon="bag"
|
|
label="Shop our products"
|
|
alt="Shopping bag"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<section class="homepage__locations">
|
|
<InteractiveGlobe />
|
|
|
|
<ScrollingTitle tag="p" class="homepage__title--world mask">
|
|
<SplitText text="World" mode="chars" />
|
|
</ScrollingTitle>
|
|
|
|
<Locations {locations} />
|
|
</section>
|
|
|
|
<div class="grid-modules">
|
|
<div class="container grid">
|
|
<div class="wrap">
|
|
<Shop />
|
|
<Newsletter />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</PageTransition>
|
|
|
|
|
|
<script context="module" lang="ts">
|
|
import { fetchAPI } from '$utils/api'
|
|
|
|
/** @type {import('@sveltejs/kit').Load} */
|
|
export async function load ({ url, params, fetch, session, stuff }) {
|
|
const res = await fetchAPI(`
|
|
query {
|
|
photo (limit: 11, sort: ["-date_created"]) {
|
|
slug
|
|
title
|
|
city
|
|
location {
|
|
name
|
|
slug
|
|
country {
|
|
slug
|
|
name
|
|
flag { id }
|
|
}
|
|
}
|
|
image { id }
|
|
}
|
|
}
|
|
`)
|
|
|
|
const { data } = res
|
|
|
|
return {
|
|
props: {
|
|
photos: data.photo,
|
|
}
|
|
}
|
|
}
|
|
</script> |