|
387 | 387 | const MIN_YEAR = SNAPSHOTS[0].year; // 1860 |
388 | 388 | const MAX_YEAR = SNAPSHOTS[SNAPSHOTS.length - 1].year; // 2025 |
389 | 389 | const SPAN = MAX_YEAR - MIN_YEAR; // 165 |
390 | | -const PREFETCH = 2; |
391 | 390 |
|
392 | 391 | function pct(year) { return ((year - MIN_YEAR) / SPAN * 100).toFixed(3) + '%'; } |
393 | 392 |
|
|
445 | 444 | function showYear(index, animate = true) { |
446 | 445 | if (index < 0 || index >= SNAPSHOTS.length) return; |
447 | 446 |
|
448 | | - const dur = animate ? 500 : 0; |
449 | | - const winStart = Math.max(0, index - PREFETCH); |
450 | | - const winEnd = Math.min(SNAPSHOTS.length - 1, index + PREFETCH); |
451 | | - |
452 | | - for (let i = winStart; i <= winEnd; i++) ensureLayer(i); |
| 447 | + const dur = animate ? 500 : 0; |
453 | 448 |
|
454 | 449 | requestAnimationFrame(() => { |
455 | | - for (let i = winStart; i <= winEnd; i++) { |
| 450 | + for (let i = 0; i < SNAPSHOTS.length; i++) { |
456 | 451 | if (!map.getLayer(lid(i))) continue; |
457 | 452 | map.setPaintProperty(lid(i), 'raster-opacity-transition', { duration: dur, delay: 0 }); |
458 | 453 | map.setPaintProperty(lid(i), 'raster-opacity', i === index ? 1 : 0); |
459 | 454 | } |
460 | 455 | }); |
461 | 456 |
|
462 | | - // Prune outside window |
463 | | - setTimeout(() => { |
464 | | - for (let i = 0; i < SNAPSHOTS.length; i++) { |
465 | | - if (i >= winStart && i <= winEnd) continue; |
466 | | - if (map.getLayer(lid(i))) map.removeLayer(lid(i)); |
467 | | - if (map.getSource(sid(i))) map.removeSource(sid(i)); |
468 | | - } |
469 | | - }, dur + 100); |
470 | | - |
471 | 457 | currentIndex = index; |
472 | 458 | updateHUD(animate); |
473 | 459 | } |
|
582 | 568 | }); |
583 | 569 |
|
584 | 570 | // ─── Boot ──────────────────────────────────────────────────── |
585 | | -map.on('load', () => showYear(currentIndex, false)); |
| 571 | +// Add all 30 layers immediately at opacity 0 so MapLibre starts fetching |
| 572 | +// tiles for every year in the background. Switching years then just flips |
| 573 | +// opacities — no layer creation delay, no tile cold-starts. |
| 574 | +map.on('load', () => { |
| 575 | + for (let i = 0; i < SNAPSHOTS.length; i++) ensureLayer(i); |
| 576 | + showYear(currentIndex, false); |
| 577 | +}); |
586 | 578 | </script> |
587 | 579 | </body> |
588 | 580 | </html> |
0 commit comments