|
5 | 5 | const base = (body?.getAttribute('data-base') || '.').trim(); |
6 | 6 | const assetVersion = '20260320h'; |
7 | 7 | const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; |
| 8 | + const SETTLE_PASS_DELAYS = [0, 140, 320, 560]; |
8 | 9 |
|
9 | 10 | const projects = [ |
10 | 11 | { |
|
95 | 96 | } |
96 | 97 | } |
97 | 98 |
|
| 99 | + function createSettledScheduler(callback) { |
| 100 | + const timers = []; |
| 101 | + |
| 102 | + const clear = () => { |
| 103 | + while (timers.length) { |
| 104 | + window.clearTimeout(timers.pop()); |
| 105 | + } |
| 106 | + }; |
| 107 | + |
| 108 | + const schedule = (baseDelay = 0, beforeSchedule) => { |
| 109 | + clear(); |
| 110 | + beforeSchedule?.(); |
| 111 | + |
| 112 | + SETTLE_PASS_DELAYS.forEach((offset) => { |
| 113 | + timers.push(window.setTimeout(callback, baseDelay + offset)); |
| 114 | + }); |
| 115 | + }; |
| 116 | + |
| 117 | + return { clear, schedule }; |
| 118 | + } |
| 119 | + |
98 | 120 | function getNavOffset(){ |
99 | 121 | const nav = document.querySelector('.nav'); |
100 | 122 | if (!nav) return 24; |
|
319 | 341 | let backdrop = document.querySelector('.nav-backdrop'); |
320 | 342 | let last = null; |
321 | 343 | let ticking = false; |
322 | | - const settleTimers = []; |
323 | 344 |
|
324 | 345 | const getScrolled = () => { |
325 | 346 | const scrollEl = document.scrollingElement || document.documentElement || document.body; |
|
357 | 378 | requestAnimationFrame(compute); |
358 | 379 | }; |
359 | 380 |
|
360 | | - const clearSettleTimers = () => { |
361 | | - while (settleTimers.length) { |
362 | | - window.clearTimeout(settleTimers.pop()); |
363 | | - } |
364 | | - }; |
365 | | - |
| 381 | + const settledChange = createSettledScheduler(onChange); |
366 | 382 | const scheduleSettledChange = (baseDelay = 0) => { |
367 | | - clearSettleTimers(); |
368 | | - resetBackdropState(); |
369 | | - [baseDelay, baseDelay + 140, baseDelay + 320, baseDelay + 560].forEach((delay) => { |
370 | | - settleTimers.push(window.setTimeout(onChange, delay)); |
371 | | - }); |
| 383 | + settledChange.schedule(baseDelay, resetBackdropState); |
372 | 384 | }; |
373 | 385 |
|
374 | 386 | compute(); |
|
968 | 980 | }; |
969 | 981 |
|
970 | 982 | let frame = 0; |
971 | | - const settleTimers = []; |
972 | | - const clearScheduledBuilds = () => { |
| 983 | + const cancelPendingBuild = () => { |
973 | 984 | window.cancelAnimationFrame(frame); |
974 | 985 | frame = 0; |
975 | | - |
976 | | - while (settleTimers.length) { |
977 | | - window.clearTimeout(settleTimers.pop()); |
978 | | - } |
979 | 986 | }; |
980 | 987 |
|
981 | 988 | const runBuild = () => new Promise((resolve) => { |
|
1003 | 1010 | }); |
1004 | 1011 | }); |
1005 | 1012 |
|
1006 | | - const scheduleBuild = (delay = 0) => { |
1007 | | - clearScheduledBuilds(); |
1008 | | - settleTimers.push(window.setTimeout(() => { |
1009 | | - runBuild(); |
1010 | | - }, delay)); |
1011 | | - }; |
1012 | | - |
| 1013 | + const settledBuild = createSettledScheduler(runBuild); |
1013 | 1014 | const scheduleSettledBuild = (baseDelay = 0) => { |
1014 | | - clearScheduledBuilds(); |
1015 | | - [baseDelay, baseDelay + 140, baseDelay + 320, baseDelay + 560].forEach((delay) => { |
1016 | | - settleTimers.push(window.setTimeout(() => { |
1017 | | - runBuild(); |
1018 | | - }, delay)); |
1019 | | - }); |
| 1015 | + settledBuild.schedule(baseDelay, cancelPendingBuild); |
1020 | 1016 | }; |
1021 | 1017 |
|
1022 | 1018 | if (document.fonts?.ready) { |
|
0 commit comments