From cee2fee8530a98ab0e6e97e9379cd49bb67243a0 Mon Sep 17 00:00:00 2001 From: tree Date: Tue, 21 Feb 2023 12:51:42 +0100 Subject: [PATCH] Smooth scroll --- src/lib/helpers.js | 11 +++++ src/routes/+layout.svelte | 84 ++++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 40 deletions(-) diff --git a/src/lib/helpers.js b/src/lib/helpers.js index 6c92c35..a5b6f17 100644 --- a/src/lib/helpers.js +++ b/src/lib/helpers.js @@ -39,4 +39,15 @@ export function animateText (ev, interval = 50) { } }, interval * i) } +} + +export async function handleAnchorClick (event) { + event.preventDefault() + const link = event.currentTarget + const anchorId = new URL(link.href).hash.replace('#', '') + const anchor = document.getElementById(anchorId || 'intro') + return window.scrollTo({ + top: anchor.offsetTop, + behavior: 'smooth' + }) } \ No newline at end of file diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 1873e51..aa61e49 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -3,19 +3,21 @@ export let data; import SvelteMarkdown from 'svelte-markdown'; - import { animateText } from '$lib/helpers'; + import { animateText, handleAnchorClick } from '$lib/helpers'; import { onMount } from 'svelte'; let navbar = false; + let choosed = null; + let lastScrollTop = null; const menu = [ - { title: 'Homepage', url: '', hidden: true }, + { title: 'intro', name: '#', url: '' }, { title: 'About', url: '#about' }, { title: 'Speakers', url: '#speakers' }, { title: 'Program', url: '#program' }, { title: 'Sponsors', url: '#sponsors' }, + { title: 'FAQ', url: '#faq' }, { title: 'Ticket', url: '#ticket', class: 'button' }, - { title: 'FAQ', url: '#faq', hidden: true } ]; const homepageAnimation = () => { @@ -25,43 +27,41 @@ } } + function locationHashUpdateTick () { + const scrollTop = document.documentElement.scrollTop || document.body.scrollTop + if (lastScrollTop === scrollTop) { + return null; + } else { + lastScrollTop = scrollTop + } + const arr = [] + for (const mi of menu) { + const el = document.getElementById(mi.title.toLowerCase()) + const pos = el.getBoundingClientRect() + //console.log(mi.title, pos.top, pos.bottom) + if (pos.top <= 100 && pos.bottom > 100) { + arr.push([ mi, pos.top, pos.bottom ]) + } + } + choosed = arr[arr.length-1] + if (choosed) { + //console.log('choosed = ', choosed[0].title) + const currentHash = window.location.hash + const hash = choosed[0].url + if (hash !== currentHash) { + if (hash === '') { + history.replaceState(null, null, ' '); + } else { + history.replaceState(null, null, hash); + } + } + } + } + onMount(async () => { setTimeout(homepageAnimation, 0) // initial animation setInterval(homepageAnimation, 10000) // every 10 seconds - - let lastScrollTop = null - - setInterval(() => { - const scrollTop = document.documentElement.scrollTop || document.body.scrollTop - if (lastScrollTop === scrollTop) { - return null; - } else { - lastScrollTop = scrollTop - } - console.log('x') - const arr = [] - for (const mi of menu) { - const el = document.getElementById(mi.title.toLowerCase()) - const pos = el.getBoundingClientRect() - //console.log(mi.title, pos.top, pos.bottom) - if (pos.top <= 100 && pos.bottom > 100) { - arr.push([ mi, pos.top, pos.bottom ]) - } - } - const choosed = arr[arr.length-1] - if (choosed) { - //console.log('choosed = ', choosed[0].title) - const currentHash = window.location.hash - const hash = choosed[0].url - if (hash !== currentHash) { - if (hash === '') { - history.replaceState(null, null, ' '); - } else { - history.replaceState(null, null, hash); - } - } - } - }, 1000) + setInterval(locationHashUpdateTick, 1000) // every 1 seconds }); @@ -77,9 +77,13 @@
- + {#each menu.filter(i => !i.hidden) as mi} - + {/each}
@@ -95,7 +99,7 @@ {/if} -
+