6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
+ import { Range } from '@angular/cdk/collections' ;
9
10
import { Directive , forwardRef , Input , OnChanges } from '@angular/core' ;
10
11
import { VIRTUAL_SCROLL_STRATEGY , VirtualScrollStrategy } from './virtual-scroll-strategy' ;
11
12
import { CdkVirtualScrollViewport } from './virtual-scroll-viewport' ;
12
13
13
14
15
+ /**
16
+ * A class that tracks the size of items that have been seen and uses it to estimate the average
17
+ * item size.
18
+ */
19
+ export class ItemSizeEstimator {
20
+ /** The total amount of weight behind the current average. */
21
+ private _totalWeight = 0 ;
22
+
23
+ /** The current average item size. */
24
+ private _averageItemSize : number ;
25
+
26
+ /** @param defaultItemSize The default size to use for items when no data is available. */
27
+ constructor ( defaultItemSize = 50 ) {
28
+ this . _averageItemSize = defaultItemSize ;
29
+ }
30
+
31
+ /** Returns the average item size. */
32
+ getAverageItemSize ( ) : number {
33
+ return this . _averageItemSize ;
34
+ }
35
+
36
+ /**
37
+ * Adds a measurement sample for the estimator to consider.
38
+ * @param range The measured range.
39
+ * @param size The measured size of the given range in pixels.
40
+ */
41
+ addSample ( range : Range , size : number ) {
42
+ const weight = range . end - range . start ;
43
+ const newTotalWeight = this . _totalWeight + weight ;
44
+ if ( newTotalWeight ) {
45
+ const newAverageItemSize =
46
+ ( size * weight + this . _averageItemSize * this . _totalWeight ) / newTotalWeight ;
47
+ if ( newAverageItemSize ) {
48
+ this . _averageItemSize = newAverageItemSize ;
49
+ this . _totalWeight = newTotalWeight ;
50
+ }
51
+ }
52
+ }
53
+ }
54
+
55
+
14
56
/** Virtual scrolling strategy for lists with items of unknown or dynamic size. */
15
57
export class AutoSizeVirtualScrollStrategy implements VirtualScrollStrategy {
16
58
/** The attached viewport. */
17
59
private _viewport : CdkVirtualScrollViewport | null = null ;
18
60
19
- /** The size of the items in the virtually scrolling list . */
61
+ /** The minimum amount of buffer rendered beyond the viewport (in pixels) . */
20
62
private _minBufferPx : number ;
21
63
22
- /** The number of buffer items to render beyond the edge of the viewport. */
64
+ /** The number of buffer items to render beyond the edge of the viewport (in pixels) . */
23
65
private _addBufferPx : number ;
24
66
67
+ /** The estimator used to estimate the size of unseen items. */
68
+ private _estimator : ItemSizeEstimator ;
69
+
25
70
/**
26
71
* @param minBufferPx The minimum amount of buffer rendered beyond the viewport (in pixels).
27
72
* If the amount of buffer dips below this number, more items will be rendered.
28
73
* @param addBufferPx The number of pixels worth of buffer to shoot for when rendering new items.
29
74
* If the actual amount turns out to be less it will not necessarily trigger an additional
30
75
* rendering cycle (as long as the amount of buffer is still greater than `minBufferPx`).
76
+ * @param estimator The estimator used to estimate the size of unseen items.
31
77
*/
32
- constructor ( minBufferPx : number , addBufferPx : number ) {
78
+ constructor ( minBufferPx : number , addBufferPx : number , estimator = new ItemSizeEstimator ( ) ) {
33
79
this . _minBufferPx = minBufferPx ;
34
80
this . _addBufferPx = addBufferPx ;
81
+ this . _estimator = estimator ;
35
82
}
36
83
37
84
/**
@@ -48,7 +95,7 @@ export class AutoSizeVirtualScrollStrategy implements VirtualScrollStrategy {
48
95
this . _viewport = null ;
49
96
}
50
97
51
- /** Called when the viewport is scrolled (debounced using requestAnimationFrame) . */
98
+ /** Called when the viewport is scrolled. */
52
99
onContentScrolled ( ) {
53
100
// TODO: do stuff.
54
101
}
@@ -58,6 +105,12 @@ export class AutoSizeVirtualScrollStrategy implements VirtualScrollStrategy {
58
105
// TODO: do stuff.
59
106
}
60
107
108
+ /**
109
+ * Update the buffer parameters.
110
+ * @param minBufferPx The minimum amount of buffer rendered beyond the viewport (in pixels).
111
+ * @param addBufferPx The number of buffer items to render beyond the edge of the viewport (in
112
+ * pixels).
113
+ */
61
114
updateBufferSize ( minBufferPx , addBufferPx ) {
62
115
this . _minBufferPx = minBufferPx ;
63
116
this . _addBufferPx = addBufferPx ;
0 commit comments