All Prompts
All Prompts

animationtext animation
Shiny Text
Анимированный текст с настраиваемым градиентным эффектом блеска. Создает эффект переливающегося текста для заголовков и акцентов.
by Zhou JasonLive Preview
Prompt
# Shiny Text
You are given a task to integrate an existing React component in the codebase
~~~/README.md
# ShinyText
A text component with a customizable shining gradient animation effect that sweeps across the text.
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `text` | string | - | The text to display and animate |
| `disabled` | boolean | false | Whether to disable the animation |
| `speed` | number | 2 | Duration of the animation in seconds |
| `className` | string | '' | Additional CSS classes for styling |
| `color` | string | '#b5b5b5' | The base color of the text |
| `shineColor` | string | '#ffffff' | The color of the shine effect |
| `spread` | number | 120 | The spread angle of the gradient in degrees |
| `yoyo` | boolean | false | Whether the animation should bounce back and forth |
| `pauseOnHover` | boolean | false | Whether to pause the animation on hover |
| `direction` | 'left' \| 'right' | 'left' | The direction of the shine movement |
| `delay` | number | 0 | Delay before animation starts (in seconds) |
## Usage
```tsx
import ShinyText from '@/sd-components/2f78ed51-fbb9-4da5-8537-b528a39fe26f';
// Basic usage
<ShinyText text="Just some shiny text!" />
// Custom speed and colors
<ShinyText
text="Shiny Text"
disabled={false}
speed={3}
className="custom-class"
color="#888888"
shineColor="#3b82f6"
/>
// Interactive usage
<ShinyText
text="Hover to pause"
pauseOnHover={true}
speed={1.5}
/>
```
~~~
~~~/src/App.tsx
import React from 'react';
import ShinyText from './ShinyText';
export default function App() {
return (
<div className="min-h-screen w-full flex items-center justify-center bg-[#1A1A1B] p-8 font-sans">
<div className="relative group rounded-3xl bg-[#222224] p-16 shadow-[0_0_40px_rgba(0,0,0,0.3)] transition-all hover:shadow-[0_0_60px_rgba(0,0,0,0.5)] border border-white/5">
<div className="text-center space-y-12">
<div>
<h2 className="text-sm font-medium text-white/40 mb-8 uppercase tracking-[0.2em]">Default Animation</h2>
<div className="text-4xl md:text-5xl font-bold tracking-tight">
<ShinyText
text="✨ Shiny Text Effect"
disabled={false}
speed={3}
className="custom-class"
/>
</div>
</div>
<div className="pt-12 border-t border-white/5 grid gap-8 justify-items-center">
<div>
<p className="text-xs text-white/30 mb-4 uppercase tracking-widest">Hover to Pause</p>
<ShinyText
text="Hover over me to pause the shine"
speed={2}
color="#888888"
shineColor="#3b82f6" // Electric blue
className="text-xl font-medium"
pauseOnHover={true}
/>
</div>
<div>
<p className="text-xs text-white/30 mb-4 uppercase tracking-widest">Yoyo Effect</p>
<ShinyText
text="Bouncing back and forth"
speed={1.5}
color="#888888"
shineColor="#ec4899" // Pink
className="text-xl font-medium"
yoyo={true}
/>
</div>
</div>
</div>
</div>
</div>
);
}
~~~
~~~/package.json
{
"name": "shiny-text-component",
"version": "1.0.0",
"description": "A shiny text animation component using Motion",
"main": "src/ShinyText.tsx",
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"motion": "^12.0.0",
"lucide-react": "^0.344.0"
}
}
~~~
~~~/src/ShinyText.tsx
import React, { useState, useCallback, useEffect, useRef } from 'react';
import { motion, useMotionValue, useAnimationFrame, useTransform } from 'motion/react';
interface ShinyTextProps {
text: string;
disabled?: boolean;
speed?: number;
className?: string;
color?: string;
shineColor?: string;
spread?: number;
yoyo?: boolean;
pauseOnHover?: boolean;
direction?: 'left' | 'right';
delay?: number;
}
const ShinyText: React.FC<ShinyTextProps> = ({
text,
disabled = false,
speed = 2,
className = '',
color = '#b5b5b5',
shineColor = '#ffffff',
spread = 120,
yoyo = false,
pauseOnHover = false,
direction = 'left',
delay = 0
}) => {
const [isPaused, setIsPaused] = useState(false);
const progress = useMotionValue(0);
const elapsedRef = useRef(0);
const lastTimeRef = useRef<number | null>(null);
const directionRef = useRef(direction === 'left' ? 1 : -1);
const animationDuration = speed * 1000;
const delayDuration = delay * 1000;
useAnimationFrame(time => {
if (disabled || isPaused) {
lastTimeRef.current = null;
return;
}
if (lastTimeRef.current === null) {
lastTimeRef.current = time;
return;
}
const deltaTime = time - lastTimeRef.current;
lastTimeRef.current = time;
elapsedRef.current += deltaTime;
// Animation goes from 0 to 100
if (yoyo) {
const cycleDuration = animationDuration + delayDuration;
const fullCycle = cycleDuration * 2;
const cycleTime = elapsedRef.current % fullCycle;
if (cycleTime < animationDuration) {
// Forward animation: 0 -> 100
const p = (cycleTime / animationDuration) * 100;
progress.set(directionRef.current === 1 ? p : 100 - p);
} else if (cycleTime < cycleDuration) {
// Delay at end
progress.set(directionRef.current === 1 ? 100 : 0);
} else if (cycleTime < cycleDuration + animationDuration) {
// Reverse animation: 100 -> 0
const reverseTime = cycleTime - cycleDuration;
const p = 100 - (reverseTime / animationDuration) * 100;
progress.set(directionRef.current === 1 ? p : 100 - p);
} else {
// Delay at start
progress.set(directionRef.current === 1 ? 0 : 100);
}
} else {
const cycleDuration = animationDuration + delayDuration;
const cycleTime = elapsedRef.current % cycleDuration;
if (cycleTime < animationDuration) {
// Animation phase: 0 -> 100
const p = (cycleTime / animationDuration) * 100;
progress.set(directionRef.current === 1 ? p : 100 - p);
} else {
// Delay phase - hold at end (shine off-screen)
progress.set(directionRef.current === 1 ? 100 : 0);
}
}
});
useEffect(() => {
directionRef.current = direction === 'left' ? 1 : -1;
elapsedRef.current = 0;
progress.set(0);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [direction]);
// Transform: p=0 -> 150% (shine off right), p=100 -> -50% (shine off left)
const backgroundPosition = useTransform(progress, p => `${150 - p * 2}% center`);
const handleMouseEnter = useCallback(() => {
if (pauseOnHover) setIsPaused(true);
}, [pauseOnHover]);
const handleMouseLeave = useCallback(() => {
if (pauseOnHover) setIsPaused(false);
}, [pauseOnHover]);
const gradientStyle: React.CSSProperties = {
backgroundImage: `linear-gradient(${spread}deg, ${color} 0%, ${color} 35%, ${shineColor} 50%, ${color} 65%, ${color} 100%)`,
backgroundSize: '200% auto',
WebkitBackgroundClip: 'text',
backgroundClip: 'text',
WebkitTextFillColor: 'transparent'
};
return (
<motion.span
className={`inline-block ${className}`}
style={{ ...gradientStyle, backgroundPosition }}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{text}
</motion.span>
);
};
export default ShinyText;
~~~
Implementation Guidelines
1. Analyze the component structure, styling, animation implementations
2. Review the component's arguments and state
3. Think through what is the best place to adopt this component/style into the design we are doing
4. Then adopt the component/design to our current system
Help me integrate this into my design