Create a component for scrolling huge titles
This commit is contained in:
@@ -35,4 +35,11 @@
|
||||
{/each}
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
{:else}
|
||||
<span class={classes}>
|
||||
{#each split as char, i}
|
||||
<span class="char" style="--i-c: {i};">{char}</span>
|
||||
{/each}
|
||||
</span>
|
||||
{/if}
|
||||
41
src/components/atoms/ScrollingTitle.svelte
Normal file
41
src/components/atoms/ScrollingTitle.svelte
Normal file
@@ -0,0 +1,41 @@
|
||||
<script lang="ts">
|
||||
import { map } from '$utils/functions'
|
||||
|
||||
export let tag: string
|
||||
export let label: string = undefined
|
||||
export let parallax: number = undefined
|
||||
export let offset: number = 0
|
||||
|
||||
let scrollY: number
|
||||
let titleEl: HTMLElement
|
||||
|
||||
$: if (titleEl) {
|
||||
const start = titleEl.offsetTop + offset
|
||||
const end = titleEl.offsetTop + (titleEl.offsetHeight + offset) * 0.9
|
||||
parallax = map(scrollY, start, end, 0, 1, true)
|
||||
}
|
||||
|
||||
const classes = [
|
||||
'scrolling-title',
|
||||
'title-huge',
|
||||
$$props.class
|
||||
].join(' ').trim()
|
||||
</script>
|
||||
|
||||
<svelte:window bind:scrollY />
|
||||
|
||||
{#if tag === 'h1'}
|
||||
<h1 class={classes} aria-label={label}
|
||||
bind:this={titleEl}
|
||||
style="--parallax-x: {parallax};"
|
||||
>
|
||||
<slot />
|
||||
</h1>
|
||||
{:else if tag === 'p'}
|
||||
<p class={classes} aria-label={label}
|
||||
bind:this={titleEl}
|
||||
style="--parallax-x: {parallax};"
|
||||
>
|
||||
<slot />
|
||||
</p>
|
||||
{/if}
|
||||
@@ -3,8 +3,10 @@
|
||||
import { page } from '$app/stores'
|
||||
// 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'
|
||||
@@ -17,8 +19,13 @@
|
||||
|
||||
const { settings, locations }: any = getContext('global')
|
||||
const { path } = $page
|
||||
|
||||
let scrollY: number, innerHeight: number
|
||||
let introTitleParallax = 0
|
||||
</script>
|
||||
|
||||
<svelte:window bind:scrollY bind:innerHeight />
|
||||
|
||||
<Metas
|
||||
title="Houses Of"
|
||||
description=""
|
||||
@@ -27,15 +34,19 @@
|
||||
|
||||
<main class="homepage">
|
||||
<section class="homepage__intro">
|
||||
<h1 style="display: none;">Houses Of The World</h1>
|
||||
<p class="homepage__title--houses title-huge">Houses</p>
|
||||
<p class="homepage__description text-medium">
|
||||
{settings.description}
|
||||
</p>
|
||||
<ScrollingTitle tag="h1" class="homepage__title--houses" label="Houses of the World" parallax={introTitleParallax} offsetTop={100}>
|
||||
<SplitText text="Houses" mode="chars" />
|
||||
</ScrollingTitle>
|
||||
|
||||
<Button text="Explore locations" url="{path}#locations">
|
||||
<IconEarth animate={true} />
|
||||
</Button>
|
||||
<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">
|
||||
@@ -79,7 +90,10 @@
|
||||
|
||||
<section class="homepage__locations" id="locations">
|
||||
<InteractiveGlobe />
|
||||
<p class="homepage__title--world title-huge">World</p>
|
||||
|
||||
<ScrollingTitle tag="p" class="homepage__title--world" parallax={introTitleParallax} offset={-1 * innerHeight / 2}>
|
||||
<SplitText text="World" mode="chars" />
|
||||
</ScrollingTitle>
|
||||
|
||||
<Locations {locations} />
|
||||
</section>
|
||||
|
||||
5
src/style/atoms/_scrolling-title.scss
Normal file
5
src/style/atoms/_scrolling-title.scss
Normal file
@@ -0,0 +1,5 @@
|
||||
.scrolling-title {
|
||||
transform: translate3d(calc(-1px * var(--parallax-x) * 100), 0, 0);
|
||||
transition: transform 1.2s var(--ease-quart);
|
||||
will-change: transform;
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
.homepage {
|
||||
// Site title
|
||||
&__title {
|
||||
// Houses
|
||||
&--houses {
|
||||
margin: -20px 0 0;
|
||||
color: $color-secondary;
|
||||
@@ -9,8 +10,15 @@
|
||||
|
||||
@include bp (sm) {
|
||||
margin-top: -100px;
|
||||
margin-left: calc(-1 * clamp(24px, 6vw, 64px));
|
||||
}
|
||||
|
||||
span {
|
||||
transition: none;
|
||||
letter-spacing: -0.06em;
|
||||
}
|
||||
}
|
||||
// World
|
||||
&--world {
|
||||
color: $color-primary-tertiary20;
|
||||
text-align: center;
|
||||
@@ -62,14 +70,22 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
// Text
|
||||
&__description {
|
||||
// Headline
|
||||
&__headline {
|
||||
max-width: 350px;
|
||||
margin: 100px auto 32px;
|
||||
margin: 100px auto 0;
|
||||
|
||||
@include bp (sm) {
|
||||
margin: 20px auto 32px;
|
||||
max-width: 524px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 24px;
|
||||
|
||||
@include bp (sm) {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
@import "atoms/discover";
|
||||
@import "atoms/box-cta";
|
||||
@import "atoms/site-title";
|
||||
@import "atoms/scrolling-title";
|
||||
@import "atoms/photo";
|
||||
|
||||
// Molecules
|
||||
|
||||
Reference in New Issue
Block a user