'use client';
import { forwardRef, HTMLAttributes, useMemo } from 'react';
export interface BloodDripProps extends HTMLAttributes {
children: string;
variant?: 'blood' | 'acid' | 'cyber' | 'void' | 'chrome';
intensity?: 'light' | 'medium' | 'heavy';
dripsPerChar?: 1 | 2 | 3;
duration?: number;
glowing?: boolean;
melting?: boolean;
showPool?: boolean;
pauseOnHover?: boolean;
static?: boolean;
dripColor?: string;
dripProbability?: number;
}
const variantColors = {
blood: '#ff0040',
acid: '#aaff00',
cyber: '#00ffff',
void: '#0a0a0a',
chrome: '#888888',
};
const dripWidths = { light: 2, medium: 4, heavy: 6 };
const dropletSizes = { light: 4, medium: 8, heavy: 12 };
export const BloodDrip = forwardRef(
(
{
children,
variant = 'blood',
intensity = 'medium',
dripsPerChar = 1,
duration = 2,
glowing = false,
melting = false,
showPool = false,
pauseOnHover = false,
static: isStatic = false,
dripColor,
dripProbability = 0.7,
className = '',
style,
...props
},
ref
) => {
const chars = children.split('');
const color = dripColor || variantColors[variant];
const dripWidth = dripWidths[intensity];
const dropletSize = dropletSizes[intensity];
const dripMap = useMemo(() => {
return chars.map(() => Math.random() < dripProbability);
}, [chars.length, dripProbability]);
const glowStyle = glowing ? { textShadow: `0 0 10px ${color}, 0 0 20px ${color}` } : {};
return (
{chars.map((char, i) => {
const hasDrip = dripMap[i] && char !== ' ';
const delay = Math.random() * 2;
return (
{char === ' ' ? '\u00A0' : char}
{hasDrip && (
)}
);
})}
{showPool && (
)}
);
}
);
BloodDrip.displayName = 'BloodDrip';
export default BloodDrip;