Use Lenis to use smooth scroll to anchors
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { addToCart } from '$utils/functions/shop'
|
||||
import { smoothScroll } from '$utils/functions'
|
||||
import { smoothScroll } from '$utils/stores'
|
||||
// Components
|
||||
import Button from '$components/atoms/Button.svelte'
|
||||
import Image from '$components/atoms/Image.svelte'
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
<div class="poster">
|
||||
{#if image}
|
||||
<a href="/shop/poster-{location.slug}" on:click={() => smoothScroll({ hash: 'poster', changeHash: false })} data-sveltekit-noscroll data-sveltekit-prefetch>
|
||||
<a href="/shop/poster-{location.slug}" data-sveltekit-noscroll data-sveltekit-prefetch
|
||||
on:click={() => $smoothScroll.scrollTo('#poster', { duration: 2 })}
|
||||
>
|
||||
<Image
|
||||
id={image.id}
|
||||
sizeKey="product"
|
||||
@@ -35,7 +37,10 @@
|
||||
size="xsmall"
|
||||
url="/shop/poster-{location.slug}"
|
||||
text="View"
|
||||
on:click={() => setTimeout(() => smoothScroll({ hash: 'poster', changeHash: false }), 1000)}
|
||||
on:click={(event) => {
|
||||
event.preventDefault()
|
||||
setTimeout(() => $smoothScroll.scrollTo('#poster', { duration: 2 }), 1000)
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
tag="button"
|
||||
|
||||
@@ -26,9 +26,7 @@
|
||||
|
||||
// Scroll to anchor
|
||||
await tick()
|
||||
$smoothScroll.scrollTo(document.getElementById('poster').offsetTop, {
|
||||
duration: 2
|
||||
})
|
||||
$smoothScroll.scrollTo('#poster', { duration: 2 })
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
import { navigating } from '$app/stores'
|
||||
import { getContext, onMount } from 'svelte'
|
||||
import { stagger, timeline } from 'motion'
|
||||
import { smoothScroll } from '$utils/stores'
|
||||
import { cartOpen } from '$utils/stores/shop'
|
||||
import { smoothScroll } from '$utils/functions'
|
||||
import { DELAY } from '$utils/contants'
|
||||
import { quartOut } from '$animations/easings'
|
||||
// Components
|
||||
@@ -117,7 +117,7 @@
|
||||
<ul data-sveltekit-noscroll data-sveltekit-prefetch>
|
||||
{#each shopLocations as { name, slug }}
|
||||
<li class:is-active={product && slug === product.location.slug}>
|
||||
<a href="/shop/poster-{slug}" on:click={() => smoothScroll({ hash: 'poster' })}>
|
||||
<a href="/shop/poster-{slug}" on:click={() => $smoothScroll.scrollTo('#poster', { duration: 2 })}>
|
||||
{name}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import { getContext, onMount } from 'svelte'
|
||||
import { timeline, stagger } from 'motion'
|
||||
import { DELAY } from '$utils/contants'
|
||||
import { smoothScroll } from '$utils/functions'
|
||||
import { smoothScroll } from '$utils/stores'
|
||||
import { getAssetUrlKey } from '$utils/api'
|
||||
import reveal from '$animations/reveal'
|
||||
import { quartOut } from '$animations/easings'
|
||||
@@ -105,7 +105,7 @@
|
||||
{settings.description}
|
||||
</p>
|
||||
|
||||
<Button url="#locations" text="Explore locations" on:click={event => smoothScroll({ hash: 'locations', event })}>
|
||||
<Button url="#locations" text="Explore locations" on:click={() => $smoothScroll.scrollTo('#locations', { duration: 2 })}>
|
||||
<IconEarth animate={true} />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -155,53 +155,6 @@ export const scrollToTop = (delay?: number) => {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Smooth Scroll to an element
|
||||
* @description Promised based
|
||||
* @url Based on: https://www.youtube.com/watch?v=oUSvlrDTLi4
|
||||
*/
|
||||
const smoothScrollPromise = (target: HTMLElement, duration: number = 1600): Promise<void> => {
|
||||
const position = target.getBoundingClientRect().top + 1
|
||||
const startPosition = window.scrollY
|
||||
const distance = position - startPosition
|
||||
let startTime: number = null
|
||||
|
||||
// Return Promise
|
||||
return new Promise((resolve) => {
|
||||
if (!(target instanceof Element)) throw new TypeError('Argument 1 must be an Element')
|
||||
if (typeof window === 'undefined') return
|
||||
|
||||
// Scroll to animation
|
||||
const animation = (currentTime: number) => {
|
||||
if (startTime === null) startTime = currentTime
|
||||
const timeElapsed = currentTime - startTime
|
||||
// Create easing value
|
||||
const easedYPosition = quartInOutFunc(timeElapsed, startPosition, distance, duration)
|
||||
// Scroll to Y position
|
||||
window.scrollTo(0, easedYPosition)
|
||||
// Loop or end animation
|
||||
if (timeElapsed < duration) {
|
||||
requestAnimationFrame(animation)
|
||||
} else {
|
||||
return resolve()
|
||||
}
|
||||
}
|
||||
|
||||
requestAnimationFrame(animation)
|
||||
})
|
||||
}
|
||||
export const smoothScroll = async ({ hash, callback, changeHash = true, event }: smoothScrollOptions) => {
|
||||
if (event) event.preventDefault()
|
||||
|
||||
const target = document.getElementById(hash)
|
||||
|
||||
smoothScrollPromise(target).then(() => {
|
||||
if (changeHash) location.hash = hash
|
||||
callback && callback()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy mailto links to clipboard and show message
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user