Screensaver
fancy/screensaverFreeComponent
A ui component.
Install it
npx shadcn@latest add https://www.fancycomponents.dev/r/screensaver.jsonSource
1"use client"23import React, { useEffect, useRef } from "react"4import {5 motion,6 useAnimationFrame,7 useMotionValue,8} from "motion/react"910import { cn } from "@/lib/utils"11import { useDimensions } from "@/hooks/use-dimensions"1213type ScreensaverProps = {14 children: React.ReactNode15 containerRef: React.RefObject<HTMLElement | null>16 speed?: number17 startPosition?: { x: number; y: number } // x,y as percentages (0-100)18 startAngle?: number // in degrees19 className?: string20}2122const Screensaver: React.FC<ScreensaverProps> = ({23 children,24 speed = 3,25 startPosition = { x: 0, y: 0 },26 startAngle = 45,27 containerRef,28 className,29}) => {30 const elementRef = useRef<HTMLDivElement>(null)31 const x = useMotionValue(0)32 const y = useMotionValue(0)33 const angle = useRef((startAngle * Math.PI) / 180)3435 const containerDimensions = useDimensions(containerRef)36 const elementDimensions = useDimensions(elementRef)3738 // Set initial position based on container dimensions and percentage39 useEffect(() => {40 if (containerDimensions.width && containerDimensions.height) {41 const initialX =42 (startPosition.x / 100) *43 (containerDimensions.width - (elementDimensions.width || 0))44 const initialY =45 (startPosition.y / 100) *46 (containerDimensions.height - (elementDimensions.height || 0))47 x.set(initialX)48 y.set(initialY)49 }50 }, [containerDimensions, elementDimensions, startPosition])5152 useAnimationFrame(() => {53 const velocity = speed54 const dx = Math.cos(angle.current) * velocity55 const dy = Math.sin(angle.current) * velocity5657 let newX = x.get() + dx58 let newY = y.get() + dy5960 // Check for collisions with container boundaries61 if (62 newX <= 0 ||63 newX + elementDimensions.width >= containerDimensions.width64 ) {65 angle.current = Math.PI - angle.current66 newX = Math.max(67 0,68 Math.min(newX, containerDimensions.width - elementDimensions.width)69 )70 }71 if (72 newY <= 0 ||73 newY + elementDimensions.height >= containerDimensions.height74 ) {75 angle.current = -angle.current76 newY = Math.max(77 0,78 Math.min(newY, containerDimensions.height - elementDimensions.height)79 )80 }8182 x.set(newX)83 y.set(newY)84 })8586 return (87 <motion.div88 ref={elementRef}89 style={{90 position: "absolute",91 top: 0,92 left: 0,93 x,94 y,95 }}96// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from fancy
All 158 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Gradient With Svganimated-gradient-with-svg | fancy | Components | Free | no deps | |
| Basic Number Tickerbasic-number-ticker | fancy | Components | Free | 1 dep | |
| Box Carouselbox-carousel | fancy | Components | Free | 1 dep | |
| Breathing Textbreathing-text | fancy | Components | Free | 1 dep | |
| Circling Elementscircling-elements | fancy | Components | Free | 1 dep | |
| Css Boxcss-box | fancy | Components | Free | 1 dep | |
| Cursor Attractor And Gravitycursor-attractor-and-gravity | fancy | Components | Free | 5 deps | |
| Drag Elementsdrag-elements | fancy | Components | Free | 1 dep |
