Advertisement

Draggable Image Track Parallax

| by Vladimir | 3 min read | code by Harshit Kumar Singh
Intermediate

Tech & Dependencies

HTML CSS JavaScript

Features

  • Drag and Drop
  • Internal Parallax
  • Web Animations API
  • Touch Support

Browser Support

Chrome 60+ Edge 79+ Firefox 55+ Safari 11+

Core

This is a Draggable Image Track Parallax component. It replaces standard scrollbars with a custom, click-and-drag horizontal interface. Its function is to provide a highly kinetic, app-like browsing experience for image galleries, featuring an internal parallax effect where the images pan slightly inside their frames as the entire track moves.

Specs

  • Weight: ~2 KB. Zero external dependencies.
  • Performance: High. It utilizes the Web Animations API (element.animate()) to interpolate the transform and object-position properties, offloading the heavy lifting to the browser’s compositor thread.
  • Theming / Customization: Minimalist. The track relies on vh/vw and vmin units, making the CSS highly scalable. Images are constrained by object-fit: cover.
  • Responsiveness: Fluid. Calculates drag distances as a percentage of window.innerWidth, ensuring the drag sensitivity feels consistent across mobile and desktop screens.
  • Web APIs: Web Animations API, Touch Events API (for mobile support).
  • Graceful Degradation: [!] High risk. If JavaScript is disabled, the gallery is completely locked in place and inaccessible. It lacks a native horizontal scroll fallback.

Anatomy

The structure separates the moving track from the fixed viewport.

  • HTML (The Skeleton): A singular #image_track container that holds a series of <img> tags. Data attributes (data-mouse-down-at, data-prev-percentage) are used natively in the DOM to store interaction state.
  • CSS (The Skin): Sets overflow: hidden on the body to disable native scrolling. Images are set to object-fit: cover and heavily rely on object-position for the internal parallax effect.
  • JS (The Nervous System): A unified event listener system that captures both mouse and touch events (onmousedown / ontouchstart). The logic calculates the delta of the drag and translates that into a percentage-based transform.

Logic

The standout feature is the Coupled Internal Parallax.

// 1. Move the entire track
track.animate({
  transform: `translate(${nextPercentage}%, -50%)`
}, { duration: 3000, fill: "forwards" });

// 2. Move the image INSIDE its frame simultaneously
for (const image of track.getElementsByClassName("image")) {
  image.animate({
    objectPosition: `${100 + nextPercentage}% center`
  }, { duration: 3000, fill: "forwards" });
}

As the user drags, the code doesn’t just slide the #image_track container horizontally. It simultaneously animates the object-position of every image inside that container. Because nextPercentage ranges from 0 to -100, the objectPosition shifts from 100% (right-aligned) to 0% (left-aligned). This means that as the track moves left, the images slowly pan to the right within their own borders, creating a striking 3D “window” effect without requiring multiple complex layers or absolute positioning.

Feel

Viscous and cinematic. The 3000ms duration in the .animate() call creates a heavy, lingering momentum. The track doesn’t snap to a halt when you release the mouse; it glides to a stop like a heavy physical object sliding on ice. The internal parallax makes the flat photographs feel like deep portals, adding a premium, editorial quality to the simple act of browsing.

Advertisement