first commit
This commit is contained in:
54
src/components/islands/SplitReveal.tsx
Normal file
54
src/components/islands/SplitReveal.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
interface Props {
|
||||
text: string;
|
||||
className?: string;
|
||||
delay?: number;
|
||||
stagger?: number;
|
||||
as?: 'span' | 'h1' | 'h2' | 'h3' | 'p' | 'div';
|
||||
}
|
||||
|
||||
export default function SplitReveal({
|
||||
text,
|
||||
className = '',
|
||||
delay = 0,
|
||||
stagger = 0.035,
|
||||
as = 'span',
|
||||
}: Props) {
|
||||
const chars = Array.from(text);
|
||||
const MotionTag = motion[as] as typeof motion.span;
|
||||
|
||||
return (
|
||||
<MotionTag
|
||||
className={className}
|
||||
initial="hidden"
|
||||
animate="show"
|
||||
aria-label={text}
|
||||
variants={{
|
||||
hidden: {},
|
||||
show: {
|
||||
transition: { staggerChildren: stagger, delayChildren: delay },
|
||||
},
|
||||
}}
|
||||
>
|
||||
{chars.map((ch, i) => (
|
||||
<motion.span
|
||||
key={i}
|
||||
aria-hidden="true"
|
||||
style={{ display: 'inline-block', whiteSpace: ch === ' ' ? 'pre' : 'normal' }}
|
||||
variants={{
|
||||
hidden: { opacity: 0, y: '0.4em', filter: 'blur(8px)' },
|
||||
show: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
filter: 'blur(0px)',
|
||||
transition: { duration: 0.5, ease: [0.22, 1, 0.36, 1] },
|
||||
},
|
||||
}}
|
||||
>
|
||||
{ch === ' ' ? '\u00A0' : ch}
|
||||
</motion.span>
|
||||
))}
|
||||
</MotionTag>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user