diff --git a/routes/_components/Timeline.html b/routes/_components/Timeline.html index 59d61888..2817f869 100644 --- a/routes/_components/Timeline.html +++ b/routes/_components/Timeline.html @@ -17,7 +17,7 @@ let i = -1 - const createData = () => fixture.slice(0, 5).map(_ => ({ + const createData = () => fixture.slice(0, 20).map(_ => ({ key: `${++i}`, props: _ })) diff --git a/routes/_components/VirtualList.html b/routes/_components/VirtualList.html index 3480ecbc..708734eb 100644 --- a/routes/_components/VirtualList.html +++ b/routes/_components/VirtualList.html @@ -1,11 +1,12 @@ -<:Window bind:scrollY='scrollY'/> +<:Window bind:scrollY='scrollY' bind:innerHeight='innerHeight' />
- {{#each $virtualItems as virtualItem, virtualIndex}} + {{#each $visibleItems as item, virtualIndex}} {{/each}}
@@ -20,12 +21,25 @@ export default { oncreate() { + console.log('scrollHeight', this.refs.node.scrollHeight) + this.store.set({ + scrollHeight: this.refs.node.scrollHeight, + }) + this.observe('innerHeight', innerHeight => { + this.store.set({ + innerHeight: innerHeight + }) + }) this.observe('items', (items) => { - this.store.set({'items': items}) + this.store.set({ + 'items': items + }) }) this.observe('scrollY', (scrollY) => { console.log('scrollY', scrollY) - this.store.set({scrollTop: scrollY}) + this.store.set({ + scrollTop: scrollY + }) }) }, data: () => ({ diff --git a/routes/_components/VirtualListItem.html b/routes/_components/VirtualListItem.html index 3f9056f7..b63bb6a7 100644 --- a/routes/_components/VirtualListItem.html +++ b/routes/_components/VirtualListItem.html @@ -1,6 +1,6 @@
@@ -22,11 +22,6 @@ itemHeights[this.get('key')] = this.refs.node.offsetHeight this.store.set({itemHeights: itemHeights}) }, - computed: { - itemOffset: ($itemOffsets, key) => { - return $itemOffsets[key] || 0 - } - }, store: () => virtualListStore } \ No newline at end of file diff --git a/routes/_utils/virtualListStore.js b/routes/_utils/virtualListStore.js index d3cd8874..3e4747d9 100644 --- a/routes/_utils/virtualListStore.js +++ b/routes/_utils/virtualListStore.js @@ -1,6 +1,8 @@ import { Store } from 'svelte/store.js' import { splice } from 'svelte-extras' +const RENDER_BUFFER = 1000 + class VirtualListStore extends Store { } @@ -9,7 +11,8 @@ VirtualListStore.prototype.splice = splice const virtualListStore = new VirtualListStore({ items: [], itemHeights: {}, - scrollTop: 0 + scrollTop: 0, + scrollHeight: 0 }) virtualListStore.compute('virtualItems', ['items'], (items) => { @@ -20,15 +23,29 @@ virtualListStore.compute('virtualItems', ['items'], (items) => { })) }) -virtualListStore.compute('itemOffsets', ['virtualItems', 'itemHeights'], (virtualItems, itemHeights) => { - let itemOffsets = {} - let totalHeight = 0 +virtualListStore.compute('visibleItems', + ['virtualItems', 'scrollTop', 'height', 'itemHeights', 'innerHeight'], + (virtualItems, scrollTop, height, itemHeights, innerHeight) => { + let visibleItems = [] + let currentOffset = 0 virtualItems.forEach(item => { let height = itemHeights[item.key] || 0 - itemOffsets[item.key] = totalHeight - totalHeight += height + console.log(item.key, 'scrollTop', scrollTop, 'currentOffset', currentOffset, 'innerHeight', innerHeight) + if ( + ((currentOffset < scrollTop) && (scrollTop - RENDER_BUFFER < currentOffset)) || + ((currentOffset >= scrollTop) && (currentOffset < (scrollTop + innerHeight + RENDER_BUFFER))) + ) { + console.log(' rendering', item) + visibleItems.push({ + item: item, + offset: currentOffset + }) + } else { + console.log('not rendering', item) + } + currentOffset += height }) - return itemOffsets + return visibleItems }) virtualListStore.compute('height', ['virtualItems', 'itemHeights'], (virtualItems, itemHeights) => {