mirror of
https://github.com/ClovertaTheTrilobita/SanYeCao-blog.git
synced 2026-10-25 13:33:53 +00:00
update header animation
This commit is contained in:
parent
dd695c8237
commit
6e4cd96114
1 changed files with 50 additions and 3 deletions
|
|
@ -118,7 +118,8 @@ const t = getTranslations(lang);
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-slot.is-exiting .site-header {
|
.header-slot.is-scroll-hidden .site-header,
|
||||||
|
.header-slot.is-footer-hidden .site-header {
|
||||||
transform: translateY(calc(-100% - 0.5rem));
|
transform: translateY(calc(-100% - 0.5rem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,6 +207,7 @@ const t = getTranslations(lang);
|
||||||
<script>
|
<script>
|
||||||
const desktopHeaderQuery = window.matchMedia("(min-width: 769px)");
|
const desktopHeaderQuery = window.matchMedia("(min-width: 769px)");
|
||||||
const HEADER_SCROLL_DISTANCE = 120;
|
const HEADER_SCROLL_DISTANCE = 120;
|
||||||
|
const DIRECTION_TRIGGER_DISTANCE = 6;
|
||||||
const headerStyleProperties = [
|
const headerStyleProperties = [
|
||||||
"--header-width",
|
"--header-width",
|
||||||
"--header-offset",
|
"--header-offset",
|
||||||
|
|
@ -246,6 +248,9 @@ const t = getTranslations(lang);
|
||||||
let headerFrame = 0;
|
let headerFrame = 0;
|
||||||
let headerMetrics: HeaderMetrics | null = null;
|
let headerMetrics: HeaderMetrics | null = null;
|
||||||
let footerDividerObserver: IntersectionObserver | null = null;
|
let footerDividerObserver: IntersectionObserver | null = null;
|
||||||
|
let lastScrollY = window.scrollY;
|
||||||
|
let scrollDirection = 0;
|
||||||
|
let directionDistance = 0;
|
||||||
|
|
||||||
const lerp = (start: number, end: number, progress: number) =>
|
const lerp = (start: number, end: number, progress: number) =>
|
||||||
start + (end - start) * progress;
|
start + (end - start) * progress;
|
||||||
|
|
@ -291,6 +296,8 @@ const t = getTranslations(lang);
|
||||||
const header = document.querySelector<HTMLElement>(".site-header");
|
const header = document.querySelector<HTMLElement>(".site-header");
|
||||||
if (!header) return;
|
if (!header) return;
|
||||||
|
|
||||||
|
updateScrollVisibility(header.parentElement, window.scrollY);
|
||||||
|
|
||||||
if (!desktopHeaderQuery.matches) {
|
if (!desktopHeaderQuery.matches) {
|
||||||
clearHeaderStyles(header);
|
clearHeaderStyles(header);
|
||||||
header.parentElement?.style.removeProperty("--header-slot-height");
|
header.parentElement?.style.removeProperty("--header-slot-height");
|
||||||
|
|
@ -369,6 +376,40 @@ const t = getTranslations(lang);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateScrollVisibility(
|
||||||
|
slot: HTMLElement | null,
|
||||||
|
currentScrollY: number,
|
||||||
|
) {
|
||||||
|
if (!slot) return;
|
||||||
|
|
||||||
|
const delta = currentScrollY - lastScrollY;
|
||||||
|
lastScrollY = currentScrollY;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!desktopHeaderQuery.matches ||
|
||||||
|
currentScrollY <= HEADER_SCROLL_DISTANCE
|
||||||
|
) {
|
||||||
|
slot.classList.remove("is-scroll-hidden");
|
||||||
|
scrollDirection = 0;
|
||||||
|
directionDistance = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Math.abs(delta) < 0.5) return;
|
||||||
|
|
||||||
|
const nextDirection = Math.sign(delta);
|
||||||
|
if (nextDirection !== scrollDirection) {
|
||||||
|
scrollDirection = nextDirection;
|
||||||
|
directionDistance = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
directionDistance += Math.abs(delta);
|
||||||
|
if (directionDistance < DIRECTION_TRIGGER_DISTANCE) return;
|
||||||
|
|
||||||
|
slot.classList.toggle("is-scroll-hidden", scrollDirection > 0);
|
||||||
|
directionDistance = 0;
|
||||||
|
}
|
||||||
|
|
||||||
function requestHeaderUpdate() {
|
function requestHeaderUpdate() {
|
||||||
if (headerFrame) return;
|
if (headerFrame) return;
|
||||||
|
|
||||||
|
|
@ -389,12 +430,12 @@ const t = getTranslations(lang);
|
||||||
|
|
||||||
if (!slot) return;
|
if (!slot) return;
|
||||||
|
|
||||||
slot.classList.remove("is-exiting");
|
slot.classList.remove("is-footer-hidden");
|
||||||
|
|
||||||
if (!desktopHeaderQuery.matches || !footerDivider) return;
|
if (!desktopHeaderQuery.matches || !footerDivider) return;
|
||||||
|
|
||||||
footerDividerObserver = new IntersectionObserver(([entry]) => {
|
footerDividerObserver = new IntersectionObserver(([entry]) => {
|
||||||
slot.classList.toggle("is-exiting", entry.isIntersecting);
|
slot.classList.toggle("is-footer-hidden", entry.isIntersecting);
|
||||||
});
|
});
|
||||||
footerDividerObserver.observe(footerDivider);
|
footerDividerObserver.observe(footerDivider);
|
||||||
}
|
}
|
||||||
|
|
@ -410,6 +451,12 @@ const t = getTranslations(lang);
|
||||||
});
|
});
|
||||||
document.addEventListener("astro:page-load", () => {
|
document.addEventListener("astro:page-load", () => {
|
||||||
headerMetrics = null;
|
headerMetrics = null;
|
||||||
|
lastScrollY = window.scrollY;
|
||||||
|
scrollDirection = 0;
|
||||||
|
directionDistance = 0;
|
||||||
|
document
|
||||||
|
.querySelector<HTMLElement>(".header-slot")
|
||||||
|
?.classList.remove("is-scroll-hidden");
|
||||||
updateHeaderState();
|
updateHeaderState();
|
||||||
bindFooterDividerObserver();
|
bindFooterDividerObserver();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue