Scroll Animation Parallax
beui/parallaxFreeComponent
Wrapper that drifts its children at a speed factor as they cross the viewport, on either axis. Reduced-motion safe.
Install it
npx shadcn@latest add https://beui.dev/r/parallax.jsonSource
1"use client";2// beui.dev/components/motion/scroll-animation34import {5 motion,6 type MotionStyle,7 useReducedMotion,8 useScroll,9 useSpring,10 useTransform,11} from "motion/react";12import { type ReactNode, type RefObject, useRef } from "react";1314import { cn } from "@/lib/utils";1516// Soft follow so the drift trails the scroll smoothly; looser than the UI17// springs in lib/ease.ts on purpose.18const PARALLAX_SPRING = { stiffness: 120, damping: 30, mass: 0.6 };1920export interface ParallaxProps {21 children: ReactNode;22 /**23 * Drift as a fraction of the element's travel through the viewport.24 * Positive moves with the scroll (foreground), negative against it25 * (background). ~0.1–0.5 reads best.26 */27 speed?: number;28 axis?: "x" | "y";29 /** Scroll container for contained scroll areas. Defaults to the viewport. */30 container?: RefObject<HTMLElement | null>;31 /** Spring-smooth the drift. Disabled automatically under reduced motion. */32 spring?: boolean;33 className?: string;34}3536export function Parallax({37 children,38 speed = 0.3,39 axis = "y",40 container,41 spring = true,42 className,43}: ParallaxProps) {44 const reduce = useReducedMotion();45 const ref = useRef<HTMLDivElement>(null);46 const { scrollYProgress } = useScroll({47 target: ref,48 container,49 offset: ["start end", "end start"],50 // Run after paint so a container ref defined higher in the tree is hydrated;51 // otherwise framer falls back to the document and only the page scroll works.52 layoutEffect: false,53 });5455 // progress 0→1 as the element crosses the viewport; map to a symmetric drift.56 const travel = speed * 100;57 const drift = useTransform(scrollYProgress, [0, 1], [travel, -travel]);58 const smoothed = useSpring(drift, PARALLAX_SPRING);59 const value = spring && !reduce ? smoothed : drift;6061 const style: MotionStyle = reduce ? {} : axis === "x" ? { x: value } : { y: value };6263 return (64 <motion.div ref={ref} style={style} className={cn(className)}>65 {children}66 </motion.div>67 );68}
What it pulls in
npm packages
Files it writes
More from beui
All 104 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Action Swap Bluraction-swap-blur | beui | Components | Free | 3 deps · 4 files | |
| Action Swap Cascadeaction-swap-cascade | beui | Components | Free | 3 deps · 4 files | |
| Action Swap Rollaction-swap-roll | beui | Components | Free | 3 deps · 4 files | |
| Agent Activityagent-activity | beui | Components | Free | 4 deps · 9 files | |
| Agent Loading States Agent Progressagent-progress | beui | Components | Free | 3 deps · 3 files | |
| AI Sidebarai-sidebar | beui | Components | Free | 4 deps · 5 files | |
| Animated Badgeanimated-badge | beui | Components | Free | 4 deps · 3 files | |
| Number Animation Animated Numberanimated-number | beui | Components | Free | 3 deps · 3 files |
