Fix header scrolling transition on public
This commit is contained in:
parent
5dba6af729
commit
2203e050bf
1 changed files with 45 additions and 40 deletions
|
|
@ -3,29 +3,37 @@
|
||||||
import SegmentedController from './SegmentedController.svelte'
|
import SegmentedController from './SegmentedController.svelte'
|
||||||
|
|
||||||
let scrollY = $state(0)
|
let scrollY = $state(0)
|
||||||
let hasScrolled = $state(false)
|
// Smooth gradient opacity from 0 to 1 over the first 100px of scroll
|
||||||
let gradientOpacity = $derived(Math.min(scrollY / 40, 1))
|
let gradientOpacity = $derived(Math.min(scrollY / 100, 1))
|
||||||
|
// Padding transition happens more quickly
|
||||||
|
let paddingProgress = $derived(Math.min(scrollY / 50, 1))
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
|
let ticking = false
|
||||||
|
|
||||||
|
const updateScroll = () => {
|
||||||
|
scrollY = window.scrollY
|
||||||
|
ticking = false
|
||||||
|
}
|
||||||
|
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
|
if (!ticking) {
|
||||||
|
requestAnimationFrame(updateScroll)
|
||||||
|
ticking = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set initial value
|
||||||
scrollY = window.scrollY
|
scrollY = window.scrollY
|
||||||
|
|
||||||
// Add hysteresis to prevent flickering
|
window.addEventListener('scroll', handleScroll, { passive: true })
|
||||||
if (!hasScrolled && scrollY > 30) {
|
|
||||||
hasScrolled = true
|
|
||||||
} else if (hasScrolled && scrollY < 20) {
|
|
||||||
hasScrolled = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('scroll', handleScroll)
|
|
||||||
return () => window.removeEventListener('scroll', handleScroll)
|
return () => window.removeEventListener('scroll', handleScroll)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header
|
<header
|
||||||
class="site-header {hasScrolled ? 'scrolled' : ''}"
|
class="site-header"
|
||||||
style="--gradient-opacity: {gradientOpacity}"
|
style="--gradient-opacity: {gradientOpacity}; --padding-progress: {paddingProgress}"
|
||||||
>
|
>
|
||||||
<div class="header-content">
|
<div class="header-content">
|
||||||
<a href="/about" class="header-link" aria-label="@jedmund">
|
<a href="/about" class="header-link" aria-label="@jedmund">
|
||||||
|
|
@ -42,14 +50,11 @@
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: $unit-5x 0;
|
// Smooth padding transition based on scroll
|
||||||
transition:
|
padding: calc($unit-5x - ($unit-5x - $unit-2x) * var(--padding-progress)) 0;
|
||||||
padding 0.3s ease,
|
|
||||||
background 0.3s ease;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
// Add a very subtle transition to smooth out any remaining jitter
|
||||||
&.scrolled {
|
transition: padding 0.1s ease-out;
|
||||||
padding: $unit-2x 0;
|
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
content: '';
|
content: '';
|
||||||
|
|
@ -60,18 +65,18 @@
|
||||||
height: 120px;
|
height: 120px;
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
to bottom,
|
to bottom,
|
||||||
rgba(0, 0, 0, calc(0.15 * var(--gradient-opacity))),
|
rgba(0, 0, 0, 0.15),
|
||||||
transparent
|
transparent
|
||||||
);
|
);
|
||||||
backdrop-filter: blur(calc(6px * var(--gradient-opacity)));
|
backdrop-filter: blur(6px);
|
||||||
-webkit-backdrop-filter: blur(calc(6px * var(--gradient-opacity)));
|
-webkit-backdrop-filter: blur(6px);
|
||||||
mask-image: linear-gradient(to bottom, black 0%, black 15%, transparent 90%);
|
mask-image: linear-gradient(to bottom, black 0%, black 15%, transparent 90%);
|
||||||
-webkit-mask-image: linear-gradient(to bottom, black 0%, black 15%, transparent 90%);
|
-webkit-mask-image: linear-gradient(to bottom, black 0%, black 15%, transparent 90%);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
opacity: var(--gradient-opacity);
|
opacity: var(--gradient-opacity);
|
||||||
transition: opacity 0.2s ease;
|
// Add a very subtle transition to smooth out any remaining jitter
|
||||||
}
|
transition: opacity 0.1s ease-out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue