INFINITYUI
HomeComponentsDocsTemplates
Star

Getting Started

  • Introduction
  • Installation
  • CLI
  • Audit

Navigation

  • Spotlight Navbar
  • Glass DockNEW
  • Animated Tab Bar
  • Circle Menu
  • Magnet Tabs
  • Animated Sidebar
  • Apple Spotlight
  • Page TOC RailNEW

Text

  • Flip Text
  • Glitch Text
  • Liquid Text
  • Flip Fade Text
  • Mask Cursor Effect

Cards

  • Glow Border Card
  • Testimonials Card
  • Interactive Book
  • Trading CardsNEW
  • Hover Image
  • Chain of ThoughtNEW
  • Masonry Grid
  • Image Pile
  • Staggered Grid

Inputs

  • AI InputNEW
  • OTP Input
  • Leave Rating

Buttons

  • Social Flip Button
  • Creepy Button

Loaders

  • Jelly Loader
  • Rolling Ball Scroll
  • Glowing Scroll

Backgrounds

  • Light Lines
  • Perspective Grid
  • Liquid Ocean
  • Eagle Vision
  • Flow Scroll
  • Horizontal Scroll

Overlays

  • PersonaNEW
  • Infinite Moving Cards
  • Masked Avatars
  • Stacked Logos
  • Icon Wheel
  • Pixelated CarouselNEW
  • Pixelated Image Trail
  • Flip Scroll
  • Interactive Folder
  • Animated Folder IconNEW
  • Stack Scroll
  • Rubik Cube
Backgrounds

Horizontal Scroll

#scroll#horizontal#cards
data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22900%22%20height%3D%22700%22%20viewBox%3D%220%200%20900%20700%22%3E%20%3Cdefs%3E%20%3ClinearGradient%20id%3D%22bg%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%22100%25%22%20y2%3D%22100%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%234338ca%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%230f172a%22%20%2F%3E%20%3C%2FlinearGradient%3E%20%3CradialGradient%20id%3D%22glow%22%20cx%3D%2278%25%22%20cy%3D%2222%25%22%20r%3D%2260%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0.35)%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0)%22%20%2F%3E%20%3C%2FradialGradient%3E%20%3C%2Fdefs%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23bg)%22%20%2F%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23glow)%22%20%2F%3E%20%3Crect%20x%3D%2245%22%20y%3D%2235%22%20width%3D%22810%22%20height%3D%22630%22%20rx%3D%2236%22%20fill%3D%22rgba(15%2C23%2C42%2C0.18)%22%20stroke%3D%22rgba(255%2C255%2C255%2C0.16)%22%20%2F%3E%20%3Crect%20x%3D%22108%22%20y%3D%22322.00000000000006%22%20width%3D%2272%22%20height%3D%22154%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22207%22%20y%3D%22252.00000000000006%22%20width%3D%2272%22%20height%3D%22224%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22306%22%20y%3D%22182.00000000000006%22%20width%3D%2272%22%20height%3D%22294%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22405%22%20y%3D%22322.00000000000006%22%20width%3D%2272%22%20height%3D%22154%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22504%22%20y%3D%22252.00000000000006%22%20width%3D%2272%22%20height%3D%22224%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22603%22%20y%3D%22182.00000000000006%22%20width%3D%2272%22%20height%3D%22294%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22546%22%20fill%3D%22white%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2276.5%22%20font-weight%3D%22700%22%3EScene%201%3C%2Ftext%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22602%22%20fill%3D%22rgba(255%2C255%2C255%2C0.72)%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2230.6%22%20font-weight%3D%22500%22%3EHorizontal%20Scroll%3C%2Ftext%3E%20%3C%2Fsvg%3E
data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22900%22%20height%3D%22700%22%20viewBox%3D%220%200%20900%20700%22%3E%20%3Cdefs%3E%20%3ClinearGradient%20id%3D%22bg%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%22100%25%22%20y2%3D%22100%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%230f766e%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%23111827%22%20%2F%3E%20%3C%2FlinearGradient%3E%20%3CradialGradient%20id%3D%22glow%22%20cx%3D%2278%25%22%20cy%3D%2222%25%22%20r%3D%2260%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0.35)%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0)%22%20%2F%3E%20%3C%2FradialGradient%3E%20%3C%2Fdefs%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23bg)%22%20%2F%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23glow)%22%20%2F%3E%20%3Crect%20x%3D%2245%22%20y%3D%2235%22%20width%3D%22810%22%20height%3D%22630%22%20rx%3D%2236%22%20fill%3D%22rgba(15%2C23%2C42%2C0.18)%22%20stroke%3D%22rgba(255%2C255%2C255%2C0.16)%22%20%2F%3E%20%3Cg%20opacity%3D%220.26%22%20stroke%3D%22rgba(255%2C255%2C255%2C0.35)%22%20fill%3D%22none%22%3E%20%3Ccircle%20cx%3D%22702%22%20cy%3D%22196.00000000000003%22%20r%3D%2272%22%20%2F%3E%20%3Ccircle%20cx%3D%22702%22%20cy%3D%22196.00000000000003%22%20r%3D%22117%22%20%2F%3E%20%3Ccircle%20cx%3D%22702%22%20cy%3D%22196.00000000000003%22%20r%3D%22162%22%20%2F%3E%20%3C%2Fg%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22546%22%20fill%3D%22white%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2276.5%22%20font-weight%3D%22700%22%3EScene%202%3C%2Ftext%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22602%22%20fill%3D%22rgba(255%2C255%2C255%2C0.72)%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2230.6%22%20font-weight%3D%22500%22%3EHorizontal%20Scroll%3C%2Ftext%3E%20%3C%2Fsvg%3E
data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22900%22%20height%3D%22700%22%20viewBox%3D%220%200%20900%20700%22%3E%20%3Cdefs%3E%20%3ClinearGradient%20id%3D%22bg%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%22100%25%22%20y2%3D%22100%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%239a3412%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%23111827%22%20%2F%3E%20%3C%2FlinearGradient%3E%20%3CradialGradient%20id%3D%22glow%22%20cx%3D%2278%25%22%20cy%3D%2222%25%22%20r%3D%2260%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0.35)%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0)%22%20%2F%3E%20%3C%2FradialGradient%3E%20%3C%2Fdefs%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23bg)%22%20%2F%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23glow)%22%20%2F%3E%20%3Crect%20x%3D%2245%22%20y%3D%2235%22%20width%3D%22810%22%20height%3D%22630%22%20rx%3D%2236%22%20fill%3D%22rgba(15%2C23%2C42%2C0.18)%22%20stroke%3D%22rgba(255%2C255%2C255%2C0.16)%22%20%2F%3E%20%3Crect%20x%3D%22108%22%20y%3D%22322.00000000000006%22%20width%3D%2272%22%20height%3D%22154%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22207%22%20y%3D%22252.00000000000006%22%20width%3D%2272%22%20height%3D%22224%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22306%22%20y%3D%22182.00000000000006%22%20width%3D%2272%22%20height%3D%22294%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22405%22%20y%3D%22322.00000000000006%22%20width%3D%2272%22%20height%3D%22154%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22504%22%20y%3D%22252.00000000000006%22%20width%3D%2272%22%20height%3D%22224%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22603%22%20y%3D%22182.00000000000006%22%20width%3D%2272%22%20height%3D%22294%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22546%22%20fill%3D%22white%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2276.5%22%20font-weight%3D%22700%22%3EScene%203%3C%2Ftext%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22602%22%20fill%3D%22rgba(255%2C255%2C255%2C0.72)%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2230.6%22%20font-weight%3D%22500%22%3EHorizontal%20Scroll%3C%2Ftext%3E%20%3C%2Fsvg%3E
data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22900%22%20height%3D%22700%22%20viewBox%3D%220%200%20900%20700%22%3E%20%3Cdefs%3E%20%3ClinearGradient%20id%3D%22bg%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%22100%25%22%20y2%3D%22100%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%237c3aed%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%23111827%22%20%2F%3E%20%3C%2FlinearGradient%3E%20%3CradialGradient%20id%3D%22glow%22%20cx%3D%2278%25%22%20cy%3D%2222%25%22%20r%3D%2260%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0.35)%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0)%22%20%2F%3E%20%3C%2FradialGradient%3E%20%3C%2Fdefs%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23bg)%22%20%2F%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23glow)%22%20%2F%3E%20%3Crect%20x%3D%2245%22%20y%3D%2235%22%20width%3D%22810%22%20height%3D%22630%22%20rx%3D%2236%22%20fill%3D%22rgba(15%2C23%2C42%2C0.18)%22%20stroke%3D%22rgba(255%2C255%2C255%2C0.16)%22%20%2F%3E%20%3Cg%20opacity%3D%220.26%22%20stroke%3D%22rgba(255%2C255%2C255%2C0.35)%22%20fill%3D%22none%22%3E%20%3Ccircle%20cx%3D%22702%22%20cy%3D%22196.00000000000003%22%20r%3D%2272%22%20%2F%3E%20%3Ccircle%20cx%3D%22702%22%20cy%3D%22196.00000000000003%22%20r%3D%22117%22%20%2F%3E%20%3Ccircle%20cx%3D%22702%22%20cy%3D%22196.00000000000003%22%20r%3D%22162%22%20%2F%3E%20%3C%2Fg%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22546%22%20fill%3D%22white%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2276.5%22%20font-weight%3D%22700%22%3EScene%204%3C%2Ftext%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22602%22%20fill%3D%22rgba(255%2C255%2C255%2C0.72)%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2230.6%22%20font-weight%3D%22500%22%3EHorizontal%20Scroll%3C%2Ftext%3E%20%3C%2Fsvg%3E
data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22900%22%20height%3D%22700%22%20viewBox%3D%220%200%20900%20700%22%3E%20%3Cdefs%3E%20%3ClinearGradient%20id%3D%22bg%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%22100%25%22%20y2%3D%22100%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%23be123c%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%23111827%22%20%2F%3E%20%3C%2FlinearGradient%3E%20%3CradialGradient%20id%3D%22glow%22%20cx%3D%2278%25%22%20cy%3D%2222%25%22%20r%3D%2260%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0.35)%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0)%22%20%2F%3E%20%3C%2FradialGradient%3E%20%3C%2Fdefs%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23bg)%22%20%2F%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23glow)%22%20%2F%3E%20%3Crect%20x%3D%2245%22%20y%3D%2235%22%20width%3D%22810%22%20height%3D%22630%22%20rx%3D%2236%22%20fill%3D%22rgba(15%2C23%2C42%2C0.18)%22%20stroke%3D%22rgba(255%2C255%2C255%2C0.16)%22%20%2F%3E%20%3Crect%20x%3D%22108%22%20y%3D%22322.00000000000006%22%20width%3D%2272%22%20height%3D%22154%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22207%22%20y%3D%22252.00000000000006%22%20width%3D%2272%22%20height%3D%22224%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22306%22%20y%3D%22182.00000000000006%22%20width%3D%2272%22%20height%3D%22294%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22405%22%20y%3D%22322.00000000000006%22%20width%3D%2272%22%20height%3D%22154%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22504%22%20y%3D%22252.00000000000006%22%20width%3D%2272%22%20height%3D%22224%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%3Crect%20x%3D%22603%22%20y%3D%22182.00000000000006%22%20width%3D%2272%22%20height%3D%22294%22%20rx%3D%2213.5%22%20fill%3D%22rgba(255%2C255%2C255%2C0.22)%22%20%2F%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22546%22%20fill%3D%22white%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2276.5%22%20font-weight%3D%22700%22%3EScene%205%3C%2Ftext%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22602%22%20fill%3D%22rgba(255%2C255%2C255%2C0.72)%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2230.6%22%20font-weight%3D%22500%22%3EHorizontal%20Scroll%3C%2Ftext%3E%20%3C%2Fsvg%3E
data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22900%22%20height%3D%22700%22%20viewBox%3D%220%200%20900%20700%22%3E%20%3Cdefs%3E%20%3ClinearGradient%20id%3D%22bg%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%22100%25%22%20y2%3D%22100%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%230369a1%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%23111827%22%20%2F%3E%20%3C%2FlinearGradient%3E%20%3CradialGradient%20id%3D%22glow%22%20cx%3D%2278%25%22%20cy%3D%2222%25%22%20r%3D%2260%25%22%3E%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0.35)%22%20%2F%3E%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22rgba(255%2C255%2C255%2C0)%22%20%2F%3E%20%3C%2FradialGradient%3E%20%3C%2Fdefs%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23bg)%22%20%2F%3E%20%3Crect%20width%3D%22900%22%20height%3D%22700%22%20rx%3D%2254%22%20fill%3D%22url(%23glow)%22%20%2F%3E%20%3Crect%20x%3D%2245%22%20y%3D%2235%22%20width%3D%22810%22%20height%3D%22630%22%20rx%3D%2236%22%20fill%3D%22rgba(15%2C23%2C42%2C0.18)%22%20stroke%3D%22rgba(255%2C255%2C255%2C0.16)%22%20%2F%3E%20%3Cg%20opacity%3D%220.26%22%20stroke%3D%22rgba(255%2C255%2C255%2C0.35)%22%20fill%3D%22none%22%3E%20%3Ccircle%20cx%3D%22702%22%20cy%3D%22196.00000000000003%22%20r%3D%2272%22%20%2F%3E%20%3Ccircle%20cx%3D%22702%22%20cy%3D%22196.00000000000003%22%20r%3D%22117%22%20%2F%3E%20%3Ccircle%20cx%3D%22702%22%20cy%3D%22196.00000000000003%22%20r%3D%22162%22%20%2F%3E%20%3C%2Fg%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22546%22%20fill%3D%22white%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2276.5%22%20font-weight%3D%22700%22%3EScene%206%3C%2Ftext%3E%20%3Ctext%20x%3D%2290%22%20y%3D%22602%22%20fill%3D%22rgba(255%2C255%2C255%2C0.72)%22%20font-family%3D%22Inter%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2230.6%22%20font-weight%3D%22500%22%3EHorizontal%20Scroll%3C%2Ftext%3E%20%3C%2Fsvg%3E
implementedInfinityUI component

This component is fully implemented in InfinityUI and wired into the docs and registry flow.

Installation

Use the registry command to add the component source, and install any package dependencies if needed.

Infinity Registry

Install the component source into your project with the shadcn CLI.

npx shadcn@latest add https://infinityui-pearl.vercel.app/r/horizontal-scroll
Package Dependencies

Install the npm packages used by this component source.

npm install framer-motion

Component Code

Copy and paste this code into your component file.

tsx
"use client";

import { useRef } from "react";
import Image from "next/image";
import { motion, type MotionValue, useScroll, useTransform } from "framer-motion";

function HorizontalScrollItem({
    image,
    index,
    isLeft,
    scrollYProgress,
    totalItems,
}: {
    image: string;
    index: number;
    isLeft: boolean;
    scrollYProgress: MotionValue<number>;
    totalItems: number;
}) {
    const direction = isLeft ? -1 : 1;
    const position = index / totalItems;

    const translateX = useTransform(
        scrollYProgress,
        [0, position, 1],
        [-index * 500 * direction, 0, (totalItems - index) * 500 * direction]
    );
    const rotateY = useTransform(
        scrollYProgress,
        [0, position, 1],
        [index * 35 * direction, 0, (totalItems - index) * -35 * direction]
    );
    const blur = useTransform(
        scrollYProgress,
        [0, position, 1],
        [index * 2, 0, (totalItems - index) * 2]
    );
    const contrast = useTransform(
        scrollYProgress,
        [0, position, 1],
        [index * 0.5, 1, (totalItems - index) * 0.5]
    );
    const translateY = useTransform(
        scrollYProgress,
        [0, position, 1],
        [(totalItems - index) * 20, totalItems * 20, index * 20]
    );
    const filter = useTransform(
        [blur, contrast],
        ([nextBlur, nextContrast]) =>
            `blur(${nextBlur}px) contrast(${nextContrast})`
    );

    return (
        <motion.div
            style={{
                translateX,
                filter,
                translateY: useTransform(translateY, (value) => `${value - 400}px`),
                perspective: 1000,
                transformStyle: "preserve-3d",
            }}
            className="absolute h-[300px] max-w-sm w-full overflow-visible rounded-xl"
        >
            <motion.div style={{ rotateY }}>
                <Image
                    src={image}
                    alt={image}
                    width={1000}
                    height={1000}
                    className="h-[300px] w-full rounded-xl object-cover"
                />
            </motion.div>
        </motion.div>
    );
}

export interface HorizontalScrollProps {
    items: { image: string }[];
}

export function HorizontalScroll({ items }: HorizontalScrollProps) {
    const ref = useRef<HTMLDivElement>(null);
    const { scrollYProgress } = useScroll({
        container: ref,
        offset: ["start start", "end end"],
    });

    return (
        <div
            ref={ref}
            className="relative w-full h-full overflow-y-auto"
            style={{ minHeight: "400px" }}
        >
            <div className="absolute top-0 left-0 w-full h-full">
                <div className="w-full" style={{ height: Math.max((items.length - 3) * 300, 300) }} />
            </div>
            <div className="sticky top-0 left-0 grid w-full h-full grid-cols-1 gap-12">
                <div className="relative flex flex-col items-center justify-center w-full h-full">
                    {items.map((item, index) => (
                        <HorizontalScrollItem
                            key={`horizontal-scroll-item-${index}`}
                            image={item.image}
                            index={index}
                            isLeft
                            scrollYProgress={scrollYProgress}
                            totalItems={items.length}
                        />
                    ))}
                </div>
            </div>
        </div>
    );
}

export default HorizontalScroll;