🚧 Switch to monorepo with Turbo
This commit is contained in:
72
apps/website/src/components/atoms/ScrollingTitle.svelte
Normal file
72
apps/website/src/components/atoms/ScrollingTitle.svelte
Normal file
@@ -0,0 +1,72 @@
|
||||
<style lang="scss">
|
||||
.scrolling-title {
|
||||
display: inline-block;
|
||||
transform: translate3d(var(--parallax-x), 0, 0);
|
||||
transition: transform 1.2s var(--ease-quart);
|
||||
will-change: transform;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { map } from '$utils/functions'
|
||||
import reveal from '$animations/reveal'
|
||||
|
||||
export let tag: string
|
||||
export let label: string = undefined
|
||||
export let parallax: number = undefined
|
||||
export let offsetStart: number = undefined
|
||||
export let offsetEnd: number = undefined
|
||||
export let animate: boolean = true
|
||||
|
||||
let scrollY: number
|
||||
let innerWidth: number
|
||||
let innerHeight: number
|
||||
let titleEl: HTMLElement
|
||||
let isLarger: boolean
|
||||
|
||||
// Define default values
|
||||
$: if (titleEl && !offsetStart && !offsetEnd) {
|
||||
offsetStart = titleEl.offsetTop - innerHeight * (innerWidth < 768 ? 0.2 : 0.75)
|
||||
offsetEnd = titleEl.offsetTop + innerHeight * (innerWidth < 768 ? 0.5 : 0.5)
|
||||
}
|
||||
|
||||
// Check if title is larger than viewport to translate it
|
||||
$: isLarger = titleEl && titleEl.offsetWidth >= innerWidth
|
||||
|
||||
// Calculate the parallax value
|
||||
$: if (titleEl) {
|
||||
const toTranslate = 100 - (innerWidth / titleEl.offsetWidth * 100)
|
||||
parallax = isLarger ? map(scrollY, offsetStart, offsetEnd, 0, -toTranslate, true) : 0
|
||||
}
|
||||
|
||||
const classes = [
|
||||
'scrolling-title',
|
||||
'title-huge',
|
||||
$$props.class
|
||||
].join(' ').trim()
|
||||
|
||||
const revealOptions = animate ? {
|
||||
children: '.char',
|
||||
animation: { y: ['-105%', 0] },
|
||||
options: {
|
||||
stagger: 0.06,
|
||||
duration: 1.6,
|
||||
delay: 0.2,
|
||||
threshold: 0.2,
|
||||
},
|
||||
} : null
|
||||
</script>
|
||||
|
||||
<svelte:window
|
||||
bind:scrollY
|
||||
bind:innerWidth bind:innerHeight
|
||||
/>
|
||||
|
||||
<svelte:element this={tag}
|
||||
bind:this={titleEl}
|
||||
class={classes} aria-label={label}
|
||||
style:--parallax-x="{parallax}%"
|
||||
use:reveal={revealOptions}
|
||||
>
|
||||
<slot />
|
||||
</svelte:element>
|
||||
Reference in New Issue
Block a user