237 lines
8.5 KiB
Svelte
237 lines
8.5 KiB
Svelte
<style lang="scss">
|
||
@import "../../style/pages/about";
|
||
</style>
|
||
|
||
<script lang="ts">
|
||
import { navigating, page } from '$app/stores'
|
||
import { onMount, afterUpdate } from 'svelte'
|
||
import type { PageData } from './$types'
|
||
import { scroll, animate, inView, timeline } from 'motion'
|
||
import { map } from '$utils/functions'
|
||
import { getAssetUrlKey } from '$utils/api'
|
||
import { DELAY } from '$utils/contants'
|
||
import { quartOut } from '$animations/easings'
|
||
// Components
|
||
import Metas from '$components/Metas.svelte'
|
||
import PageTransition from '$components/PageTransition.svelte'
|
||
import Image from '$components/atoms/Image.svelte'
|
||
import Button from '$components/atoms/Button.svelte'
|
||
import AboutGridPhoto from '$components/atoms/AboutGridPhoto.svelte'
|
||
import Heading from '$components/molecules/Heading.svelte'
|
||
import ProcessStep from '$components/molecules/ProcessStep.svelte'
|
||
import Banner from '$components/organisms/Banner.svelte'
|
||
|
||
export let data: PageData
|
||
const { about, photos } = data
|
||
|
||
let scrollY: number, innerWidth: number, innerHeight: number
|
||
let photosGridEl: HTMLElement
|
||
let currentStep: number = 0
|
||
let photosGridOffset: number = photosGridEl && photosGridEl.offsetTop
|
||
|
||
$: currentStep = $page.url.hash ? Number($page.url.hash.split('#step-')[1]) - 1 : 0
|
||
$: parallaxPhotos = photosGridEl && map(scrollY, photosGridOffset - innerHeight, photosGridOffset + innerHeight / 1.5, 0, innerHeight * 0.15, true)
|
||
$: fadedPhotosIndexes = innerWidth > 768
|
||
? [0, 2, 5, 7, 9, 12, 17, 20, 22, 26, 30, 32, 34]
|
||
: [1, 4, 5, 7, 11, 14, 17, 20, 24, 27, 30, 33, 34, 36, 40, 43]
|
||
|
||
const introText = about.intro_text
|
||
.replace('<strong>',
|
||
`<a href="/${about.intro_firstlocation.country.slug}/${about.intro_firstlocation.slug}" data-sveltekit-noscroll data-sveltekit-prefetch>
|
||
<img src="${getAssetUrlKey(about.intro_firstlocation.country.flag.id, 'square-small-jpg')}" width="32" height="32" alt="${about.intro_firstlocation.country.flag.title}">
|
||
<strong>
|
||
`)
|
||
.replace('</strong>', '</strong></a>')
|
||
|
||
|
||
onMount(() => {
|
||
/**
|
||
* Animations
|
||
*/
|
||
// const animation = timeline([
|
||
// // Heading
|
||
// ['.heading .text', {
|
||
// y: [24, 0],
|
||
// opacity: [0, 1],
|
||
// z: 0,
|
||
// }, {
|
||
// at: 0.5,
|
||
// }],
|
||
|
||
// // First photo
|
||
// [photoFirstEl, {
|
||
// y: ['10%', 0],
|
||
// rotate: [0, getComputedStyle(photoFirstEl).getPropertyValue('--rotate')],
|
||
// opacity: [0, 1],
|
||
// z: 0,
|
||
// }, {
|
||
// at: 0.75,
|
||
// opacity: {
|
||
// duration: 1
|
||
// }
|
||
// }],
|
||
|
||
// // Portrait photo
|
||
// [photoUsEl, {
|
||
// y: ['10%', 0],
|
||
// x: [0, '5%'],
|
||
// rotate: [0, 5],
|
||
// opacity: [0, 1],
|
||
// z: 0,
|
||
// }, {
|
||
// at: 1,
|
||
// opacity: {
|
||
// duration: 1
|
||
// }
|
||
// }],
|
||
|
||
// // Text
|
||
// ['.about__introduction .text', {
|
||
// y: [32, 0],
|
||
// opacity: [0, 1],
|
||
// z: 0,
|
||
// }, {
|
||
// at: 1.2,
|
||
// }],
|
||
// ], {
|
||
// delay: $navigating ? DELAY.PAGE_LOADING / 1000 : 0,
|
||
// defaultOptions: {
|
||
// duration: 1.6,
|
||
// easing: quartOut,
|
||
// },
|
||
// })
|
||
// animation.stop()
|
||
|
||
// // Run animation
|
||
// requestAnimationFrame(animation.play)
|
||
})
|
||
|
||
|
||
afterUpdate(() => {
|
||
// Update photos grid top offset
|
||
photosGridOffset = photosGridEl.offsetTop
|
||
})
|
||
</script>
|
||
|
||
<svelte:window bind:scrollY bind:innerWidth bind:innerHeight />
|
||
|
||
<Metas
|
||
title="About the project – Houses Of"
|
||
description={about.description}
|
||
image=""
|
||
/>
|
||
|
||
|
||
<PageTransition name="about">
|
||
<Banner
|
||
title="About"
|
||
image={{
|
||
id: '699b4050-6bbf-4a40-be53-d84aca484f9d',
|
||
alt: 'Photo caption',
|
||
}}
|
||
/>
|
||
|
||
<section class="about__introduction">
|
||
<div class="container grid">
|
||
<h2 class="title-small">Meet the makers</h2>
|
||
<p class="heading text-big">We are a French and Australian couple that found each other through our mutual <strong>passion for travel, photography and design</strong>.</p>
|
||
|
||
<div class="text text-small">
|
||
<p>With a strong desire to create, we’re award winning in our own fields with <a href="">Félix</a> as a Digital Designer and Art Director and <a href="">Shelby</a> as a Front-End Developer.</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<div class="about__creation">
|
||
<div class="container grid">
|
||
<figure class="first-photo">
|
||
<Image
|
||
class="shadow-box-dark"
|
||
id={about.intro_firstphoto.id}
|
||
alt={about.intro_firstphoto.title}
|
||
sizeKey="photo-list"
|
||
sizes={{
|
||
small: { width: 400 },
|
||
medium: { width: 600 },
|
||
large: { width: 800 },
|
||
}}
|
||
ratio={1.5}
|
||
/>
|
||
<figcaption class="text-info">
|
||
{about.intro_firstphoto_caption}<br>
|
||
in
|
||
<a href="/{about.intro_firstlocation.country.slug}/{about.intro_firstlocation.slug}" data-sveltekit-noscroll data-sveltekit-prefetch>
|
||
<img src="{getAssetUrlKey(about.intro_firstlocation.country.flag.id, 'square-small-jpg')}" width="32" height="32" alt="{about.intro_firstlocation.country.flag.title}">
|
||
<span>Naarm Australia (Melbourne)</span>
|
||
</a>
|
||
</figcaption>
|
||
</figure>
|
||
</div>
|
||
</div>
|
||
|
||
<section class="about__process">
|
||
<div class="container grid">
|
||
<aside>
|
||
<div class="heading">
|
||
<h2 class="title-medium">{about.process_title}</h2>
|
||
<p class="text-normal">{about.process_subtitle}</p>
|
||
</div>
|
||
|
||
<ol>
|
||
{#each about.process_steps as { title }, index}
|
||
<li class:is-active={index === currentStep}>
|
||
<a href="#step-{index + 1}" class="title-big">
|
||
<span>{title}</span>
|
||
</a>
|
||
</li>
|
||
{/each}
|
||
</ol>
|
||
</aside>
|
||
|
||
<div class="steps">
|
||
{#each about.process_steps as { text, image, video_mp4, video_webm }, index}
|
||
<ProcessStep
|
||
{index} {text}
|
||
image={image ?? undefined}
|
||
video={video_mp4 && video_webm ? {
|
||
mp4: video_mp4.id,
|
||
webm: video_webm.id
|
||
} : undefined}
|
||
visible={index === currentStep}
|
||
/>
|
||
{/each}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="about__photos" bind:this={photosGridEl}>
|
||
<div class="container-wide">
|
||
<div class="photos-grid" style:--parallax-y="{parallaxPhotos}px">
|
||
{#each photos as { image: { id }, title }, index}
|
||
<AboutGridPhoto class="grid-photo"
|
||
{id}
|
||
alt={title}
|
||
disabled={fadedPhotosIndexes.includes(index)}
|
||
/>
|
||
{/each}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="about__interest grid">
|
||
<div class="container grid">
|
||
<h2 class="title-xl">{about.contact_title}</h2>
|
||
<div class="blocks">
|
||
{#each about.contact_blocks as { title, text, link, button }}
|
||
<div class="block">
|
||
<h3 class="text-label">{title}</h3>
|
||
<p class="text-normal">{text}</p>
|
||
{#if link}
|
||
<Button size="small" url={link} text={button} />
|
||
{/if}
|
||
</div>
|
||
{/each}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</PageTransition> |