kinda sorta working

This commit is contained in:
Nolan Lawson 2018-01-15 16:12:07 -08:00
parent 3f9ca66e38
commit 7682015cda
4 changed files with 47 additions and 21 deletions

View file

@ -17,7 +17,7 @@
let i = -1
const createData = () => fixture.slice(0, 5).map(_ => ({
const createData = () => fixture.slice(0, 20).map(_ => ({
key: `${++i}`,
props: _
}))

View file

@ -1,11 +1,12 @@
<:Window bind:scrollY='scrollY'/>
<:Window bind:scrollY='scrollY' bind:innerHeight='innerHeight' />
<div class="virtual-list" ref:node style="height: {{$height}}px;">
<!-- <div class="virtual-list-viewport" ref:viewport></div> -->
{{#each $virtualItems as virtualItem, virtualIndex}}
{{#each $visibleItems as item, virtualIndex}}
<VirtualListItem :component
props="{{virtualItem.props}}"
index="{{virtualItem.index}}"
key="{{virtualItem.key}}"
offset="{{item.offset}}"
props="{{item.item.props}}"
index="{{item.item.index}}"
key="{{item.item.key}}"
/>
{{/each}}
</div>
@ -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: () => ({

View file

@ -1,6 +1,6 @@
<div class="virtual-list-item"
ref:node
style="transform: translate3d(0, {{itemOffset}}px, 0);"
style="transform: translate3d(0, {{offset}}px, 0);"
data-virtual-index="{{index}}"
data-virtual-key="{{key}}"
>
@ -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
}
</script>

View file

@ -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) => {