Skip to content

gaomeng1900/advanced-scroll-hook

Repository files navigation

advanced-scroll-hook

npm version CI/CD License: MIT

A powerful React hook for advanced scroll tracking, control, and animations. Perfect for creating scroll-based interactions, progress indicators, parallax effects, and intelligent scroll snapping.

Features

  • ๐ŸŽฏ Precise Scroll Tracking - Track scroll position, percentage, and direction
  • ๐ŸŽฎ Smooth Scroll Control - Programmatically control scroll with smooth animations
  • ๐Ÿ“ Custom Range Support - Define custom scroll ranges for specific elements
  • ๐Ÿ”„ Direction Detection - Detect scroll direction (up/down/none)
  • ๐Ÿ“ฑ Responsive Design - Automatically adapts to window resize
  • ๐ŸŽจ Animation Ready - Perfect for scroll-based animations and effects
  • ๐Ÿš€ TypeScript Support - Full TypeScript support with type definitions

Installation

npm install advanced-scroll-hook

Quick Start

import { useScroll } from 'advanced-scroll-hook'

function MyComponent() {
  const { scrollData, setScroll } = useScroll()
  
  return (
    <div>
      <div>Scroll: {scrollData.percent * 100}%</div>
      <button onClick={() => setScroll(0, true)}>
        Go to Top
      </button>
    </div>
  )
}

API Reference

useScroll(options?)

Returns an object with scroll data and control functions.

Parameters

interface UseScrollOptions {
  container?: HTMLElement | null    // Custom scroll container (default: window)
  startHeight?: number             // Start position in pixels (default: 0)
  endHeight?: number              // End position in pixels (default: document height)
}

Return Value

interface UseScrollReturn {
  scrollData: {
    scrollY: number        // Current scroll position in pixels
    percent: number        // Scroll percentage (0-1, can exceed bounds)
    direction: 'up' | 'down' | 'none'  // Scroll direction
    isScrolling: boolean   // Whether currently scrolling
  }
  percentToScrollHeight: (percent: number) => number  // Convert percent to pixels
  setScroll: (position: number, smooth?: boolean) => void  // Scroll to position
}

Examples

Basic Usage

import { useScroll } from 'advanced-scroll-hook'

function ScrollProgress() {
  const { scrollData } = useScroll()
  
  return (
    <div className="progress-bar">
      <div 
        className="progress-fill"
        style={{ width: `${scrollData.percent * 100}%` }}
      />
    </div>
  )
}

Key Div Demo - Custom Range Tracking

Track scroll progress for a specific element within the viewport:

// Calculate scroll range for the target element
const calculateScrollRange = useCallback(() => {
  const rect = keyDivRef.current.getBoundingClientRect()
  const keyDivTop = rect.top + window.scrollY
  
  return {
    startHeight: keyDivTop,  // When div top hits screen top
    endHeight: keyDivTop + rect.height - window.innerHeight
  }
}, [])

const { scrollData } = useScroll({
  startHeight: scrollRange.startHeight,
  endHeight: scrollRange.endHeight,
})

// Animate based on scroll progress
<div style={{
  transform: `scale(${0.8 + scrollData.percent * 0.4})`,
  opacity: scrollData.percent < 0 || scrollData.percent > 1 ? 0.3 : 1
}}>
  Content scales as you scroll!
</div>

Three Pages Demo - Scroll-Based Navigation

Create a three-page experience with scroll-based navigation:

// Calculate current page based on scroll percentage
const getCurrentPage = (percent: number) => {
  if (percent < 0.3333) return 1
  if (percent < 0.6666) return 2
  return 3
}

// Jump to specific page
const goToPage = (page: number) => {
  const targetPercent = page === 1 ? 0 : page === 2 ? 0.5 : 1
  const targetHeight = percentToScrollHeight(targetPercent)
  setScroll(targetHeight, true)
}

// Navigation buttons
{[1, 2, 3].map((page) => (
  <button onClick={() => goToPage(page)}>
    {page}
  </button>
))}

Smart Snap Demo - Intelligent Scroll Snapping

Create intelligent directional scroll snapping with threshold-based page navigation:

// Smart snapping logic with 15% threshold
const handleSmartSnap = useCallback(() => {
  const snapPoints = [0, 0.5, 1]
  const distanceFromLast = Math.abs(scrollData.percent - lastSnapPositionRef.current)
  const threshold = 0.15
  
  if (distanceFromLast < threshold) return
  
  let targetSnap = null
  if (scrollData.direction === 'down') {
    targetSnap = snapPoints.find(point => point > lastSnapPositionRef.current)
  } else if (scrollData.direction === 'up') {
    targetSnap = snapPoints.reverse().find(point => point < lastSnapPositionRef.current)
  }
  
  if (targetSnap !== null) {
    setScroll(percentToScrollHeight(targetSnap), true)
    lastSnapPositionRef.current = targetSnap
  }
}, [scrollData.percent, scrollData.direction])

// Trigger snapping when scroll stops
useEffect(() => {
  if (!scrollData.isScrolling) {
    setTimeout(handleSmartSnap, 50)
  }
}, [scrollData.isScrolling, handleSmartSnap])

Use Cases

  • Reading Progress Indicators - Show how much of an article has been read
  • Parallax Scrolling Effects - Create depth and motion in your designs
  • Scroll-Based Animations - Trigger animations based on scroll position
  • Section Navigation - Highlight current section in navigation
  • Infinite Scroll - Load more content as user scrolls
  • Scroll Snapping - Create smooth page-like scrolling experiences
  • Custom Scroll Behaviors - Implement unique scroll interactions

Development

# Install dependencies
npm install

# Start demo development server
npm run dev

# Build library
npm run build:lib

# Build demo
npm run build:demo

# Build both
npm run build

Project Structure

src/
โ”œโ”€โ”€ lib/          # Library source
โ”‚   โ”œโ”€โ”€ index.ts  # Main export
โ”‚   โ””โ”€โ”€ useScroll.ts # Hook implementation
โ””โ”€โ”€ demo/         # Demo application
    โ”œโ”€โ”€ App.tsx   # Demo app with examples
    โ”œโ”€โ”€ main.tsx
    โ””โ”€โ”€ index.html

License

MIT ยฉ gaomeng1900

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published