Skip to content

Element Viewport Tracking

createElementTracker(element) — tracks an element's position relative to the viewport (its rect, how far it's traveled through the viewport, and its distance from the viewport's center), updated on the shared requestAnimationFrame loop.

ts
function createElementTracker(element: HTMLElement): ElementTracker

Return value

getState()

() => ElementTrackerState

Reads the current state synchronously, without subscribing.

subscribe(callback)

(callback: (state: ElementTrackerState) => void) => () => void

Calls callback immediately with the current state, then again only when the state actually changes (a shallow field comparison — no notification on an rAF tick where nothing moved). Returns an unsubscribe function.

destroy()

() => void

ElementTrackerState

FieldTypeNotes
rectDOMRectLikeA plain { top, left, right, bottom, width, height } snapshot of getBoundingClientRect().
viewportProgressnumber0..1 — from the element entering at the viewport's bottom edge to leaving at its top edge.
distanceFromCenternumberPixel offset between the element's vertical center and the viewport's vertical center — negative when the element is above center.

Without a window (server-side rendering), this returns a static tracker whose state is always { rect: { top: 0, left: 0, right: 0, bottom: 0, width: 0, height: 0 }, viewportProgress: 0, distanceFromCenter: 0 }.

Example:

ts
import { createElementTracker } from '@macrulez/inview-core'

const tracker = createElementTracker(document.querySelector('#card')!)

tracker.subscribe((state) => {
  console.log(`${Math.round(state.viewportProgress * 100)}% through the viewport`)
})

Looking for the reactive version, or a ready-made parallax effect? See Element Viewport Position and Parallax Layer for Vue, or React Hooks for React.