Files
housesof/src/routes/index.svelte

190 lines
5.3 KiB
Svelte

<script lang="ts">
import { getContext, onMount } from 'svelte'
import { fade } from 'svelte/transition'
import { page } from '$app/stores'
import anime from 'animejs'
import { DURATION } from '$utils/contants'
// Components
import Metas from '$components/Metas.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 PhotoCard from '$components/molecules/PhotoCard.svelte'
import InteractiveGlobe from '$components/organisms/InteractiveGlobe.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')
const { path } = $page
let scrollY: number, innerHeight: number
onMount(() => {
// Setup animations
const introTimeline = anime.timeline({
duration: 1600,
easing: 'easeOutQuart',
})
// Reveal text
introTimeline.add({
targets: '.homepage__headline',
translateY: [16, 0],
opacity: [0, 1],
}, 900)
// Animate collage photos
introTimeline.add({
targets: '.homepage__collage .photo-card',
translateY: ['33.333%', 0],
rotate (item: HTMLElement) {
// Get target CSS variable for rotation
const rotateEnd = getComputedStyle(item).getPropertyValue('--rotation')
return [-4, rotateEnd]
},
opacity: [0, 1],
duration: 1200,
delay: anime.stagger(75),
}, 0)
})
</script>
<svelte:window bind:scrollY bind:innerHeight />
<Metas
title="Houses Of"
description=""
image=""
/>
<main class="homepage"
in:fade={{ duration: DURATION.PAGE_IN, delay: DURATION.PAGE_OUT }}
out:fade={{ duration: DURATION.PAGE_OUT }}
>
<section class="homepage__intro">
<ScrollingTitle
tag="h1"
class="homepage__title--houses"
label="Houses of the World"
offsetTop={100}
>
<SplitText text="Houses" mode="chars" />
</ScrollingTitle>
<div class="homepage__headline">
<p class="text-medium">
{settings.description}
</p>
<Button text="Explore locations" url="{path}#locations">
<IconEarth animate={true} />
</Button>
</div>
</section>
<section class="homepage__photos">
<div class="homepage__collage">
{#each photos as { slug, title, image, location, city }}
<PhotoCard
id={image.id}
alt={title}
url="/{location.country.slug}/{location.slug}/{slug}"
title={title}
location={location}
city={city}
/>
{/each}
</div>
</section>
<div class="homepage__ctas" id="ctas">
<DiscoverText />
<div class="cards">
<BoxCTA
url="{path}#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" id="locations">
<InteractiveGlobe />
<ScrollingTitle
tag="p"
class="homepage__title--world mask"
offset={-1 * innerHeight / 2}
>
<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>
</main>
<script context="module" lang="ts">
import { fetchAPI } from '$utils/api'
export async function load ({ page, 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>