Electric Text
scrollxui/electric-textFreeComponent
Animated electric text with glowing, distorted outline-solid for dynamic neon effects.
Live preview
live · rendered by the registry
Rendered by scrollxui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://scrollxui.dev/registry/electric-text.jsonSource
1'use client';23import React, {4 useCallback,5 useEffect,6 useId,7 useLayoutEffect,8 useRef,9 useState,10} from 'react';11import { cn } from '@/lib/utils';1213type ElectricTextProps = {14 children: React.ReactNode;15 color?: string;16 speed?: number;17 chaos?: number;18 strokeWidth?: number;19 className?: string;20 glowIntensity?: 'low' | 'medium' | 'high';21 fillColor?: string;22 showFill?: boolean;23};2425function hexToRgba(hex: string, alpha = 1): string {26 if (!hex) return `rgba(0,0,0,${alpha})`;27 let h = hex.replace('#', '');28 if (h.length === 3) {29 h = h30 .split('')31 .map((c) => c + c)32 .join('');33 }34 const int = parseInt(h, 16);35 const r = (int >> 16) & 255;36 const g = (int >> 8) & 255;37 const b = int & 255;38 return `rgba(${r}, ${g}, ${b}, ${alpha})`;39}4041const ElectricText: React.FC<ElectricTextProps> = ({42 children,43 color = '#5227FF',44 speed = 1,45 chaos = 1,46 strokeWidth = 2,47 className = '',48 glowIntensity = 'medium',49 fillColor = 'rgba(0,0,0,0.8)',50 showFill = true,51}) => {52 const rawId = useId().replace(/[:]/g, '');53 const filterId = `text-turbulent-${rawId}`;54 const svgRef = useRef<SVGSVGElement | null>(null);55 const measureRef = useRef<HTMLDivElement | null>(null);56 const [svgFontSize, setSvgFontSize] = useState(120);5758 const updateAnim = useCallback(() => {59 const svg = svgRef.current;60 if (!svg) return;6162 const dyAnims = Array.from(63 svg.querySelectorAll<SVGAnimateElement>(64 'feOffset > animate[attributeName="dy"]',65 ),66 );67 const dxAnims = Array.from(68 svg.querySelectorAll<SVGAnimateElement>(69 'feOffset > animate[attributeName="dx"]',70 ),71 );7273 const baseDur = 6;74 const dur = Math.max(0.001, baseDur / (speed || 1));75 [...dyAnims, ...dxAnims].forEach((a) => a.setAttribute('dur', `${dur}s`));7677 const disp = svg.querySelector('feDisplacementMap');78 if (disp) disp.setAttribute('scale', String(30 * (chaos || 1)));7980 requestAnimationFrame(() => {81 [...dyAnims, ...dxAnims].forEach((a: SVGAnimateElement) => {82 if (typeof a.beginElement === 'function') {83 try {84 a.beginElement();85 } catch {}86 }87 });88 });89 }, [speed, chaos]);9091 useEffect(() => {92 updateAnim();93 }, [updateAnim]);9495 useLayoutEffect(() => {96 if (measureRef.current) {97 const computedStyle = window.getComputedStyle(measureRef.current);98 const fontSize = parseFloat(computedStyle.fontSize);99// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from scrollxui
All 180 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | scrollxui | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | scrollxui | Components | Free | 7 deps | |
| Animated Buttonanimated-button | scrollxui | Components | Free | 4 deps | |
| Animated Tabsanimated-tabs | scrollxui | Components | Free | 1 dep | |
| Animated Testimonialsanimated-testimonials | scrollxui | Components | Free | 2 deps | |
| Animated TextGenerateanimated-textgenerate | scrollxui | Components | Free | 3 deps | |
| Announcementannouncement | scrollxui | Components | Free | 5 deps | |
| Aspect Ratioaspect-ratio | scrollxui | Components | Free | 1 dep |
