3D Scenes Powered by Virtual Scrolling

3D Scenes Powered by Virtual Scrolling

3 Min Read

The interest in 3D experiences online continues to grow, yet there’s a significant challenge in using traditional DOM-based animation with emerging 3D canvas options. Traditional scroll events link animations to the DOM’s scroll position, which is restrictive in controlling a 3D scene. Virtual scrolling alters this by using scroll data to directly control animations independently of the actual scroll position.

This article explores the constraints of traditional DOM-based scrolling, showcases how virtual scrolling enhances scroll-driven interactions, and demonstrates a responsible implementation.

The Problem with Traditional Approaches

The Intersection Observer is great for detecting elements entering the viewport and triggering animations. However, it falls short for 3D scenes, where the canvas often occupies the entire viewport as a single element, leaving nothing to observe. Adding DOM elements just to trigger animations in the canvas ties two rendering systems with differing abstractions, complicating scene management as complexity grows. Continuous animations also suffer as Intersection Observer gives callbacks at threshold points, not continuous frame-by-frame data, hindering smooth 3D transitions.

GSAP’s ScrollTrigger offers better control over scroll-linked timelines. However, it assumes native scrolling as the backbone, requiring adaptations for a canvas-contained scene. Virtual scrolling captures scroll input to manipulate the scene directly using scroll data without traditional scrolling.

This method unlocks creative possibilities unreachable by traditional means. Scroll data can drive any property, like morphing materials or triggering particle effects. The scroll value becomes a timeline you fully control. You define the physics, timing, and overall experience.

The main challenge is implementing it responsibly, ensuring scroll behavior expectations, such as progress indicators, keyboard navigation, and screen reader context, are met.

Virtual Scrolling Fundamentals

The core idea is separating user input from native scroll positions. First, intercept wheel input and prevent default behavior:

let scrollTarget = 0;
let scrollCurrent = 0;
const maxScroll = 88;

window.addEventListener('wheel', (e) => {
  e.preventDefault();
  scrollTarget += e.deltaY * 0.01;
  scrollTarget = Math.max(0, Math.min(maxScroll, scrollTarget));
}, { passive: false });

The scrollTarget variable is derived from user input. The setup with { passive: false } allows preventDefault() to stop native scrolling. The wheel delta is converted into scene units by multiplying by 0.01, aligning it more closely with the 3D scene scale.

Use Clamping to Prevent Overscroll

Use clamping to prevent overscroll, keeping the scroll target within a bounded range.

scrollTarget = Math.max(0, Math.min(maxScroll, scrollTarget));

This line imposes a hard lower and upper bound on scrolling. The maximum value reflects the length of your scene content,, preventing movement into empty space.

Connecting Scroll to the Scene

Scroll input data is used to transform scenes, like updating camera

You might also like