Typographytypographycyberpunkdecodeglitchmatrix
Hacker Decode Text
Scrambled character reveal that decodes into clear text.
Live Preview
CYBERNETIC PROTOCOL ONLINE
Usage
Copy and paste this code into your React component:
tsx
import { HackerDecodeText } from 'react-component-kit-ui/typography';
<HackerDecodeText text="CYBERNETIC_INTERFACE_INITIALIZED" speed={40} />Manual Installation
If you are not using the npm package, create a new file and paste the following code: src/components/HackerDecodeText.tsx + HackerDecodeText.css:
HackerDecodeText.tsx
'use client';
import { useEffect, useRef } from 'react';
import './HackerDecodeText.css';
/** class:list โ className */
function cx(...args: unknown[]): string {
const out: string[] = [];
const walk = (v: unknown) => {
if (!v) return;
if (typeof v === 'string' || typeof v === 'number') out.push(String(v));
else if (Array.isArray(v)) v.forEach(walk);
else if (typeof v === 'object') for (const [k, on] of Object.entries(v as Record<string, unknown>)) if (on) out.push(k);
};
args.forEach(walk);
return out.join(' ');
}
/**
* HackerDecodeText โ Cyberpunk Matrix-style randomized character deciphering effect on hover.
*
* @param {string} text - Final decoded text string. Default is 'CYBERNETIC SYSTEM READY'.
* @param {string} tag - HTML heading or paragraph tag. Default is 'h3'.
* @param {string} className - Optional CSS class names.
*/
export interface HackerDecodeTextProps {
text?: string;
tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'p' | 'span';
className?: string;
}
export function HackerDecodeText({
text = 'CYBERNETIC PROTOCOL ONLINE',
tag: Tag = 'h3',
className = '',
}: HackerDecodeTextProps) {
// Ported from the Astro <script>: runs once after mount (DOM logic kept as in the Astro kit).
const mounted = useRef(false);
useEffect(() => {
if (mounted.current) return;
mounted.current = true;
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+-=[]{}|;:,.<>?';
function setupHackerText() {
document.querySelectorAll('[data-hacker-text]').forEach((el) => {
if (el.getAttribute('data-hacker-init')) return;
el.setAttribute('data-hacker-init', 'true');
const original = el.getAttribute('data-hacker-text') || el.textContent || '';
let interval: any = null;
el.addEventListener('pointerenter', () => {
let iteration = 0;
clearInterval(interval);
interval = setInterval(() => {
el.textContent = original
.split('')
.map((char, index) => {
if (char === ' ') return ' ';
if (index < iteration) {
return original[index];
}
return chars[Math.floor(Math.random() * chars.length)];
})
.join('');
if (iteration >= original.length) {
clearInterval(interval);
}
iteration += 1 / 2;
}, 30);
});
});
}
setupHackerText();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<>
<Tag className={cx(['hacker-text', className])} data-hacker-text={text} title="Hover to decode" data-rk-415ed5="">
{text}
</Tag>
</>
);
}
export default HackerDecodeText;HackerDecodeText.css
/* HackerDecodeText โ ported from astro-component-kit (typography/HackerDecodeText.astro) */
.hacker-text:where([data-rk-415ed5]) {
font-family: var(--font-mono, 'JetBrains Mono', monospace);
font-size: clamp(1.2rem, 3vw, 2rem);
font-weight: 800;
color: var(--c-primary-light, #d4a017);
letter-spacing: 0.08em;
cursor: default;
user-select: none;
transition: text-shadow 0.2s ease;
}
.hacker-text:hover:where([data-rk-415ed5]) {
text-shadow: 0 0 12px rgba(212, 160, 23, 0.7);
}Quick Info
- Category
- Typography
- Filename
HackerDecodeText.tsx- Dependencies
- None โ pure React + CSS
- Tags
- typographycyberpunkdecodeglitchmatrix