I’m creating a website that shows a grid of black rectangles on HTML, and I want text boxes to appear when the user scrolls that appear above the rectangles and remain there for some time for the user to read, similar to here: https://mkorostoff.github.io/1-pixel-wealth/.
I’ve tried to do this with a combination of HTML and JS but have been unsuccessful so far, as the text boxes aren’t appearing on the screen.
document.addEventListener('DOMContentLoaded', (event) => {
const gridContainer = document.getElementById('grid');
const infoBoxes = [{
title: 'Information Box 1',
content: 'This is some information about the conflict.'
}, {
title: 'Information Box 2',
content: 'More details and statistics.'
}, {
title: 'Information Box 3',
content: 'Additional context and historical background.'
}];
const totalRectangles = 3000; // Total number of rectangles (example value)
const scrollThreshold = 100; // Number of rectangles to scroll past before showing the next info box
const stickyDuration = 400; // Number of pixels the info box should remain sticky
let currentInfoBoxIndex = -1;
let currentInfoBox = null;
for (let i = 0; i < totalRectangles; i++) {
const square = document.createElement('div');
square.classList.add('grid-item');
gridContainer.appendChild(square);
}
// Function to check if an element is in viewport
function isElementInViewport(el) {
const rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
// Function to handle scroll event
function handleScroll() {
const scrollPosition = window.scrollY || window.pageYOffset;
const rectanglesScrolled = Math.floor(scrollPosition / 200); // Assuming each rectangle height is 200px
console.log("rectangles", rectanglesScrolled)
// Determine which info box to show based on scroll position
const infoBoxIndex = Math.floor(rectanglesScrolled / scrollThreshold);
if (infoBoxIndex !== currentInfoBoxIndex) {
// Remove the current info box if it exists
if (currentInfoBox) {
currentInfoBox.classList.remove('visible', 'sticky');
}
// Add the new info box if it exists in the array
if (infoBoxIndex < infoBoxes.length) {
currentInfoBoxIndex = infoBoxIndex;
currentInfoBox = document.querySelectorAll('.info-box')[infoBoxIndex];
console.log(currentInfoBox)
currentInfoBox.classList.add('visible', 'sticky');
} else {
currentInfoBoxIndex = -1;
currentInfoBox = null;
}
}
// Remove the sticky class after the sticky duration
if (currentInfoBox) {
const infoBoxRect = currentInfoBox.getBoundingClientRect();
if (infoBoxRect.top < 20 || infoBoxRect.bottom > stickyDuration) {
currentInfoBox.classList.remove('sticky');
}
}
}
// Listen for scroll events
window.addEventListener('scroll', handleScroll);
// Initial check in case some boxes are already in view
handleScroll();
});
<div id="grid" class="grid-container"></div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>