|
3 | 3 |
|
4 | 4 | const body = document.body; |
5 | 5 | const base = (body?.getAttribute('data-base') || '.').trim(); |
6 | | - const assetVersion = '20260410s'; |
| 6 | + const assetVersion = '20260410t'; |
7 | 7 | const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; |
8 | 8 | const SETTLE_PASS_DELAYS = [0, 140, 320, 560]; |
9 | 9 | const simpleIcon = (name) => `https://cdn.jsdelivr.net/npm/simple-icons@v11/icons/${name}.svg`; |
|
1038 | 1038 | return; |
1039 | 1039 | } |
1040 | 1040 |
|
| 1041 | + const revealElement = (element, observer) => { |
| 1042 | + if (element.classList.contains("is-visible")) { |
| 1043 | + return; |
| 1044 | + } |
| 1045 | + element.classList.add("is-visible"); |
| 1046 | + observer?.unobserve?.(element); |
| 1047 | + }; |
| 1048 | + |
| 1049 | + const inView = (element) => { |
| 1050 | + const rect = element.getBoundingClientRect(); |
| 1051 | + const vh = window.innerHeight || document.documentElement.clientHeight; |
| 1052 | + const vw = window.innerWidth || document.documentElement.clientWidth; |
| 1053 | + return rect.bottom > 0 && rect.right > 0 && rect.top < vh && rect.left < vw; |
| 1054 | + }; |
| 1055 | + |
1041 | 1056 | const observer = new IntersectionObserver( |
1042 | 1057 | (entries, obs) => { |
1043 | 1058 | entries.forEach((entry) => { |
1044 | 1059 | if (!entry.isIntersecting) { |
1045 | 1060 | return; |
1046 | 1061 | } |
1047 | | - entry.target.classList.add("is-visible"); |
1048 | | - obs.unobserve(entry.target); |
| 1062 | + revealElement(entry.target, obs); |
1049 | 1063 | }); |
1050 | 1064 | }, |
1051 | 1065 | { |
1052 | | - rootMargin: "0px 0px -10% 0px", |
1053 | | - threshold: 0.12 |
| 1066 | + root: null, |
| 1067 | + rootMargin: "0px 0px -1% 0px", |
| 1068 | + threshold: 0 |
1054 | 1069 | } |
1055 | 1070 | ); |
1056 | 1071 |
|
1057 | 1072 | revealElements.forEach((element) => observer.observe(element)); |
| 1073 | + const revealVisibleNow = () => { |
| 1074 | + revealElements.forEach((element) => { |
| 1075 | + if (!element.classList.contains("is-visible") && inView(element)) { |
| 1076 | + revealElement(element, observer); |
| 1077 | + } |
| 1078 | + }); |
| 1079 | + }; |
| 1080 | + requestAnimationFrame(revealVisibleNow); |
1058 | 1081 | settleHeroReveal(observer); |
1059 | 1082 | requestAnimationFrame(() => settleHeroReveal(observer)); |
1060 | | - window.setTimeout(() => settleHeroReveal(observer), 120); |
1061 | | - window.addEventListener("pageshow", () => settleHeroReveal(observer)); |
| 1083 | + window.setTimeout(() => { |
| 1084 | + settleHeroReveal(observer); |
| 1085 | + revealVisibleNow(); |
| 1086 | + }, 120); |
| 1087 | + window.addEventListener("resize", revealVisibleNow); |
| 1088 | + window.addEventListener("pageshow", () => { |
| 1089 | + settleHeroReveal(observer); |
| 1090 | + revealVisibleNow(); |
| 1091 | + }); |
1062 | 1092 | } |
1063 | 1093 |
|
1064 | 1094 | function initHeroIntro() { |
|
0 commit comments