|
14 | 14 | index = Math.max(0, Math.min(itemCount - 1, index + amount));
|
15 | 15 | };
|
16 | 16 |
|
| 17 | + const getCached = (index) => $visibleData.find(({ index: i }) => i === index)?.data || get(index); |
| 18 | +
|
| 19 | + let inRange = [-Infinity, Infinity]; |
| 20 | + const initialized = writable(false); |
17 | 21 | const dim = writable({ w: 0, h: 0 });
|
18 | 22 | const offset = spring(0, { stiffness, damping });
|
| 23 | +
|
19 | 24 | export const visibleData = derived(
|
20 |
| - [dim, offset], |
21 |
| - ([{ w, h }, $o]) => { |
22 |
| - if (!w || !h || !intiailized) return []; |
| 25 | + [dim, offset, initialized], |
| 26 | + ([{ w, h }, $o, $initialized]) => { |
| 27 | + if (!w || !h || !$initialized) return []; |
| 28 | + if ($o < inRange[0] || $o > inRange[1]) return $visibleData; |
23 | 29 | const cellHeight = h / cellCount;
|
24 | 30 | const start = Math.max(-1, Math.floor((-1 * $o) / cellHeight) - 1);
|
25 | 31 | const baseOffset = $o % cellHeight;
|
|
28 | 34 | .map((_, i) => {
|
29 | 35 | const index = i + start;
|
30 | 36 | const pos = baseOffset + (i - 1) * cellHeight;
|
31 |
| - // don't recalculate unnecessarily |
32 |
| - if ($visibleData?.[i]?.index === index) return { ...$visibleData[i], pos }; |
33 | 37 | if (index < 0 || index >= itemCount) return undefined;
|
34 |
| - return { data: get(index), pos, index }; |
| 38 | + return { data: getCached(index), pos, index }; |
35 | 39 | })
|
36 | 40 | .filter(Boolean);
|
37 | 41 | },
|
38 | 42 | []
|
39 | 43 | );
|
40 | 44 |
|
41 |
| - let intiailized = false; |
| 45 | + const updateOffset = (o) => { |
| 46 | + inRange = [o, $offset].sort((a, b) => a - b); |
| 47 | + offset.set(o, { hard: !$initialized }); |
| 48 | + }; |
42 | 49 |
|
43 | 50 | $: type = vertical ? 'rows' : 'columns';
|
44 | 51 | $: gridStyle = `grid-template-${type}: repeat(${cellCount}, 1fr);`;
|
45 | 52 | $: {
|
46 | 53 | if ($dim.w && $dim.h) {
|
47 |
| - const newOffset = ((-1 * $dim.h) / cellCount) * index; |
48 |
| - offset.set(+newOffset.toFixed(2), { hard: !intiailized }); |
49 |
| - if (!intiailized) intiailized = true; |
| 54 | + const newOffset = ($dim.h / cellCount) * index * -1; |
| 55 | + updateOffset(+newOffset.toFixed(3)); |
| 56 | + if (!$initialized) initialized.set(true); |
50 | 57 | }
|
51 | 58 | }
|
52 | 59 | </script>
|
|
0 commit comments