JSFiddle - React, Tailwind, and code Playground

by tonyleeper

HTML

<virtual-tile-view></virtual-tile-view>

CSS

virtual-tile-view {
    width: 100%;
    height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
}

virtual-tile-view .scroller {
    position: relative; 
    overflow-y: hidden;
}

virtual-tile-view .tile {
    position: absolute;
    display: inline-block;
}

JavaScript

var target = document.getElementsByTagName('virtual-tile-view');

var VirtualTileView = function () {
    var VirtualTileView = function (element, spec) {
        this.initialize(spec);
        this.calculateMeasures(spec);
        this.render();
    };
    
    VirtualTileView.prototype.initialize = function (spec) {
        this.element = element;
        this.tileRenderer = spec.tileRenderer;
        this.data = spec.data;
        this.moreData = spec.moreData || false;        
    };
    
    VirtualTileView.prototype.calcluateMeasures = function (spec) {
        var self = this;        
        this.measures = {
            minTileWidth: spec.minTileWidth,
            aspectRatio: spec.referenceTileHeight / spec.referenceTileWidth,
            tileMargin: spec.tileMargin,
            
            displayWidth: self.element.clientWidth,
            displayHeight: self.element.clientHeight,
            
            columnCount: Math.max(Math.floor(this.displayWidth / this.minTileWidth), 1),
            virtualTileWidth: (this.displayWidth - (this.tileMargin * (this.columnCount + 1))) / this.columnCount,
            renderedTileWidth: Math.floor(this.virtualTileWidth),
            
            virtualTileHeight: this.virtualTileWidth * this.aspectRatio,
            renderedTileHeight: Math.floor(this.virtualTileHeight),
            rowCount: Math.ceil(this.displayHeight / this.virtualTileHeight) + 1
        };
        
        // only render complete rows unless we have all the data
        if (this.moreData) {
            this.measures.totalRowCount = Math.floor(this.data.length / this.measures.columnCount);
        } else {
            this.measures.totalRowCount = Math.ceil(this.data.length / this.measures.columnCount);
        }
        
        this.measures.scrollHeight = this.measures.virtualTileHeight * this.measures.totalRowCount + this.measures.tileMargin * (this.measures.totalRowCount + 1);
    };
    
   ...