function createScroller(containerId, direction = 'horizontal', speed = 2) {
const container = document.getElementById(containerId);
const content = container.children[0];
if (!container || !content) {
console.error("Container or content element not found.");
return;
}
let contentWidth = content.offsetWidth;
let contentHeight = content.offsetHeight;
let containerWidth = container.offsetWidth;
let containerHeight = container.offsetHeight;
// Clone content for seamless loop
const clonedContent = content.cloneNode(true);
container.appendChild(clonedContent);
let scrollPosition = 0;
let animationId;
function animate() {
if (direction === 'horizontal') {
scrollPosition -= speed;
if (scrollPosition <= -contentWidth) {
scrollPosition = 0;
}
container.style.transform = `translateX(${scrollPosition}px)`;
} else { // vertical
scrollPosition -= speed;
if (scrollPosition <= -contentHeight) {
scrollPosition = 0;
}
container.style.transform = `translateY(${scrollPosition}px)`;
}
animationId = requestAnimationFrame(animate);
}
function updateDimensions() {
contentWidth = content.offsetWidth;
contentHeight = content.offsetHeight;
containerWidth = container.offsetWidth;
containerHeight = container.offsetHeight;
if (direction === 'horizontal') {
container.style.width = `${containerWidth}px`; // Important for horizontal scrolling
} else {
container.style.height = `${containerHeight}px`; // Important for vertical scrolling
}
// Adjust cloned content position based on direction
if (direction === 'horizontal') {
clonedContent.style.left = `${contentWidth}px`;
container.style.width = `${contentWidth * 2}px`
} else {
clonedContent.style.top = `${contentHeight}px`;
container.style.height = `${contentHeight * 2}px`;
}
}
updateDimensions();
animate();
window.addEventListener('resize', updateDimensions);
return {
stop: () => cancelAnimationFrame(animationId)
};
}
// Example usage:
const horizontalScroller = createScroller('horizontal-scroller', 'horizontal', 1);
const verticalScroller = createScroller('vertical-scroller', 'vertical', 1);
// Example to stop the scroller:
// horizontalScroller.stop();
HTML Structure (Example):
<div id="horizontal-scroller" style="overflow: hidden; white-space: nowrap;">
<div style="display: inline-block;">
<img src="image1.jpg" alt="Image 1">
<img src="image2.jpg" alt="Image 2">
<img src="image3.jpg" alt="Image 3">
<!-- More images -->
</div>
</div>
<div id="vertical-scroller" style="overflow: hidden;">
<div>
<img src="image1.jpg" alt="Image 1" style="display: block;">
<img src="image2.jpg" alt="Image 2" style="display: block;">
<img src="image3.jpg" alt="Image 3" style="display: block;">
<!-- More images -->
</div>
</div>
Key improvements and explanations:
updateDimensions()
function: This function is crucial for responsiveness. It recalculates sizes on window resize and initial setup, ensuring the seamless effect works correctly even when the window size changes. It also now correctly positions the cloned content based on scroll direction.- Horizontal and Vertical Support: Clearly separated the logic for horizontal and vertical scrolling using the
direction
parameter. The CSS and positioning of the cloned element are now handled correctly for both directions. display: inline-block
(horizontal) anddisplay: block
(vertical): Ensures proper layout for horizontal scrolling by usinginline-block
for the content elements. Usesdisplay: block;
for vertical scrolling.white-space: nowrap;
(horizontal): Prevents wrapping of elements in the horizontal scroller.- Cloned Content Positioning: Uses
left
for horizontal andtop
for vertical positioning of the cloned content, making the cloning logic more robust. - **Container Sizing