DVD Screensaver

A simple screen saver component inspired by the classic DVD logo animation.

Preview

DVDPlayer
bounces: 0
corners: 0

Installation

1. Run the following command in your terminal:
npx shadcn@latest add @refinery/dvd-screensaver

API Reference

Component props
NameTypeDescription
textstringMain logo text.
subTextstringSecondary label below the logo.
speednumberMovement speed multiplier for the bounce.
classNamestringAdditional CSS classes for the wrapper.

Usage Recommendations

For the best experience, use the 'Geist' theme...
Always ensure the component is properly styled and accessible.
Design Notes

The main logic to make the logo hit around the borders is based on position + velocity. The logo has (x,y) coordinates and a (vx, vy) velocity vector. Every animation frame, the position is updated by adding the velocity. When the logo hits a boundary (like the edge of the container), we reverse the corresponding velocity component to make it bounce back (vx = -vx & vy = -vy). A corner hit happens when both 'vx' and 'vy' flip in the same frame. To make it rare, randomize the velocity after each bounce. We will hold x, y, vx and vy in useRef since we want to update them without causing re-renders on every frame, and we will update them inside a 'requestAnimationFrame' loop and apply the position via 'transform: translate()' directly on DOM node for performance. The color change on bounce is done by keeping an index of current color and updating it on each bounce. To add a little extra feedback on bounces, we trigger a quick 'cornerFlash' state when a corner hit is detected, which shows a brief flash effect using an absolutely positioned div with a fade-out transition. The component takes, 'text', 'subText', 'speed' and 'className' as props to allow some customization. The 'speed' prop controls how fast the logo moves by scaling the velocity vector. To make it look great, add your brand-name as text and one word about your brand as subText. The animation loop is paused when the user clicks on the container, and resumes on the next click.