Marquee
nyxui/marqueeFreeComponent
A customizable, interactive scrolling marquee component.
Live preview
live · rendered by the registry
Rendered by shadcn/ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://nyxui.com/r/marquee.jsonSource
1"use client";2import { cn } from "@/lib/utils";3import { useMotionValue, animate, motion } from "motion/react";4import { useState, useEffect, useRef } from "react";56export type MarqueeProps = {7 children: React.ReactNode;8 gap?: number;9 speed?: number;10 speedOnHover?: number;11 direction?: "horizontal" | "vertical";12 reverse?: boolean;13 className?: string;14 fadeEdges?: boolean;15 fadeWidth?: number;16 pauseOnTap?: boolean;17 draggable?: boolean;18};1920export function Marquee({21 children,22 gap = 16,23 speed = 100,24 speedOnHover,25 direction = "horizontal",26 reverse = false,27 className,28 fadeEdges = false,29 fadeWidth = 64,30 pauseOnTap = true,31 draggable = true,32}: MarqueeProps) {33 const [currentSpeed, setCurrentSpeed] = useState(speed);34 const [isPaused, setIsPaused] = useState(false);35 const [isDragging, setIsDragging] = useState(false);36 const containerRef = useRef<HTMLDivElement>(null);37 const translation = useMotionValue(0);38 const [isTransitioning, setIsTransitioning] = useState(false);39 const [key, setKey] = useState(0);40 const dragStartPosition = useRef(0);41 const [dimensions, setDimensions] = useState({ width: 0, height: 0 });4243 useEffect(() => {44 if (!containerRef.current) return;4546 const currentRef = containerRef.current;4748 const updateDimensions = () => {49 if (currentRef) {50 const rect = currentRef.getBoundingClientRect();51 setDimensions({52 width: rect.width,53 height: rect.height,54 });55 }56 };5758 updateDimensions();5960 const resizeObserver = new ResizeObserver(updateDimensions);61 resizeObserver.observe(currentRef);6263 return () => {64 resizeObserver.unobserve(currentRef);65 resizeObserver.disconnect();66 };67 }, []);6869 const { width, height } = dimensions;7071 useEffect(() => {72 let controls;7374 if (isPaused || isDragging || (!width && !height)) {75 return () => {};76 }7778 const size = direction === "horizontal" ? width : height;79 const contentSize = size + gap;8081 if (!size) return () => {};8283 const from = reverse ? -contentSize / 2 : 0;84 const to = reverse ? 0 : -contentSize / 2;85 const distanceToTravel = Math.abs(to - from);86 const duration = distanceToTravel / currentSpeed;8788 if (isTransitioning) {89 const remainingDistance = Math.abs(translation.get() - to);90 const transitionDuration = remainingDistance / currentSpeed;9192 controls = animate(translation, [translation.get(), to], {93// … truncated
What it pulls in
npm packages
Files it writes
More from shadcn/ui
All 68 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| 3D Layered Card3d-layered-card | shadcn/ui | Components | Free | 1 dep | |
| Animated Code Blockanimated-code-block | shadcn/ui | Components | Free | 3 deps | |
| Animated Grainy Backgroundanimated-grainy-bg | shadcn/ui | Components | Free | 1 dep | |
| Animated Textanimated-text | shadcn/ui | Components | Free | 1 dep | |
| Apple Glass Effectapple-glass-effect | shadcn/ui | Components | Free | 1 dep | |
| Bubble Backgroundbubble-background | shadcn/ui | Components | Free | no deps | |
| Custom Cursorcustom-cursor | shadcn/ui | Components | Free | 1 dep | |
| Cyberpunk Cardcyberpunk-card | shadcn/ui | Components | Free | no deps |
