76 lines
2.0 KiB
TypeScript
76 lines
2.0 KiB
TypeScript
'use client';
|
|
|
|
import React from 'react';
|
|
import { motion, Variants } from 'framer-motion';
|
|
import { cn } from '@/components/ui';
|
|
|
|
interface ScribbleProps {
|
|
variant: 'circle' | 'underline';
|
|
className?: string;
|
|
color?: string;
|
|
}
|
|
|
|
export default function Scribble({ variant, className, color = '#82ed20' }: ScribbleProps) {
|
|
const pathVariants: Variants = {
|
|
hidden: { pathLength: 0, opacity: 0 },
|
|
visible: {
|
|
pathLength: 1,
|
|
opacity: 1,
|
|
transition: {
|
|
duration: 1.8,
|
|
ease: 'easeInOut',
|
|
},
|
|
},
|
|
};
|
|
|
|
if (variant === 'circle') {
|
|
return (
|
|
<svg
|
|
className={cn('absolute pointer-events-none', className)}
|
|
aria-hidden="true"
|
|
viewBox="0 0 800 350"
|
|
preserveAspectRatio="none"
|
|
>
|
|
<motion.path
|
|
variants={pathVariants}
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={{ once: true }}
|
|
transform="matrix(0.9791300296783447,0,0,0.9791300296783447,400,179)"
|
|
strokeLinejoin="miter"
|
|
fillOpacity="0"
|
|
strokeMiterlimit="4"
|
|
stroke={color}
|
|
strokeOpacity="1"
|
|
strokeWidth="20"
|
|
d=" M253,-161 C253,-161 -284.78900146484375,-201.4600067138672 -376,-21 C-469,163 67.62300109863281,174.2100067138672 256,121 C564,34 250.82899475097656,-141.6929931640625 19.10700035095215,-116.93599700927734"
|
|
/>
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
if (variant === 'underline') {
|
|
return (
|
|
<svg
|
|
className={cn('absolute pointer-events-none', className)}
|
|
aria-hidden="true"
|
|
viewBox="-400 -55 730 60"
|
|
preserveAspectRatio="none"
|
|
>
|
|
<motion.path
|
|
variants={pathVariants}
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={{ once: true }}
|
|
d="m -383.25 -6 c 55.25 -22 130.75 -33.5 293.25 -38 c 54.5 -0.5 195 -2.5 401 15"
|
|
stroke={color}
|
|
strokeWidth="20"
|
|
fill="none"
|
|
/>
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
return null;
|
|
}
|