JSFiddle - React, Tailwind, and code Playground
by AndyE
HTML
<!-- Based on https://jsfiddle.net/upsuper/yvhLdf71/ -->
<div id="wrapper">
<canvas id="canvas" width="200" height="200"></canvas>
<div id="inner"></div>
</div>
CSS
#wrapper {
position: relative;
width: 200px;
height: 200px;
overflow: auto;
background: white;
transform: translate(1px, 1px);
}
#inner {
width: 1px;
}
#canvas {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
JavaScript
const ctx = canvas.getContext('2d');
const rowHeight = 40;
const rowWidth = 200;
const numRows = 10000000;
const rowsPerView = canvas.height / rowHeight;
let rendering = false;
ctx.fillStyle = 'blue';
ctx.strokeStyle = 'gray';
ctx.font = '20px Verdana';
inner.style.height = `${rowHeight * numRows}px`;
function drawRows() {
rendering = false;
ctx.clearRect(0, 0, 200, 200);
const scroll = wrapper.scrollTop;
const viewHeight = rowsPerView * rowHeight;
canvas.style.top = `${ scroll }px`;
for (let i = 0; i <= rowsPerView; i++) {
const row = Math.floor(scroll / rowHeight) + i;
const offset = (rowHeight - (scroll % rowHeight)) + ((i -1) * rowHeight);
ctx.strokeRect(0, offset, rowWidth, rowHeight);
ctx.fillText(`Row ${row}`, 10, offset + 30);
}
}
drawRows();
wrapper.addEventListener('scroll', () => {
if (!rendering && wrapper.scrollTop >= 0 && wrapper.scrollTop <= inner.offsetHeight) {
rendering = true;
requestAnimationFrame(drawRows);
}
});