Files
housesof/src/routes/index.svelte

158 lines
4.7 KiB
Svelte

<style lang="scss">
@import "../style/pages/homepage";
</style>
<script lang="ts">
import { page } from '$app/stores'
import { getContext, onMount } from 'svelte'
import anime, { type AnimeTimelineInstance } from 'animejs'
import { DELAY } from '$utils/contants'
import { sleep, smoothScroll } 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 InteractiveGlobe2 from '$components/organisms/InteractiveGlobe2.svelte'
import Collage from '$components/organisms/Collage.svelte'
import Locations from '$components/organisms/Locations.svelte'
import ListCTAs from '$components/organisms/ListCTAs.svelte'
import ShopModule from '$components/organisms/ShopModule.svelte'
import NewsletterModule from '$components/organisms/NewsletterModule.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="{settings.seo_name}{settings.seo_title}"
description={settings.seo_description}
image=""
/>
<PageTransition name="homepage">
<section class="homepage__intro"
use:reveal={{
animation: animeFade,
options: {
duration: 1000,
},
}}
>
<ScrollingTitle
tag="h1"
class="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 url="#locations" text="Explore locations" on:click={event => smoothScroll({ hash: 'locations', event })}>
<IconEarth animate={true} />
</Button>
</div>
</section>
<section class="homepage__photos">
<Collage {photos} />
</section>
<div class="homepage__ctas">
<DiscoverText />
<ListCTAs>
<li>
<BoxCTA
url="{$page.url.pathname}"
icon="globe"
label="Discover locations"
alt="Globe"
on:click={() => smoothScroll('locations')}
/>
</li>
<li>
<BoxCTA
url="/photos"
icon="photos"
label="Browse all photos"
alt="Photos"
/>
</li>
<li>
<BoxCTA
url="/shop"
icon="bag"
label="Shop our products"
alt="Shopping bag"
/>
</li>
</ListCTAs>
</div>
<section class="homepage__locations" id="locations">
<InteractiveGlobe2 />
<ScrollingTitle tag="p" class="title-world mask">
<SplitText text="World" mode="chars" />
</ScrollingTitle>
<Locations {locations} />
</section>
<div class="grid-modules">
<div class="container grid">
<div class="wrap">
<ShopModule />
<NewsletterModule />
</div>
</div>
</div>
</PageTransition>