Last active
August 20, 2023 20:55
-
-
Save DarlonHenrique/2910dc561d751d84b9c7980a7e20f19c to your computer and use it in GitHub Desktop.
component with cool hacker effect in the letters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use client' | |
import React, { useEffect, useRef } from 'react' | |
import { VariantProps, tv } from 'tailwind-variants' | |
const textStyle = tv({ | |
base: 'text-6xl font-bold font-mono text-black dark:text-white', | |
variants: { | |
size: { | |
sm: 'text-sm', | |
md: 'text-base', | |
lg: 'text-lg', | |
xl: 'text-xl', | |
'2xl': 'text-2xl', | |
'3xl': 'text-3xl', | |
'4xl': 'text-4xl', | |
'5xl': 'text-5xl', | |
'6xl': 'text-6xl' | |
}, | |
defaultVariants: { | |
size: 'md' | |
} | |
} | |
}) | |
type TextVariants = VariantProps<typeof textStyle> | |
interface HackerTextProps extends TextVariants { | |
children: string | |
runOnRender?: boolean | |
className?: string | |
} | |
export function HackerText({ children, runOnRender = true, size, className }: HackerTextProps) { | |
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+-=<>?|{}[]~' // you can put any characters you want | |
const getRandomNumber = () => Math.floor(Math.random() * 12) // generate a random number interger and greater than 0 | |
const getRandomCharacter = () => characters[getRandomNumber()] // get a random character from the characters string | |
const textRef = useRef<HTMLHeadingElement>(null) | |
function randomizeLetters() { | |
let iterations = 0 | |
let originalText = children | |
const interval = setInterval(() => { | |
const splittedText = textRef.current!.innerText.split('') | |
textRef.current!.innerText = splittedText | |
.map((letter, index) => { | |
if (index < iterations) return originalText[index] | |
if (letter === ' ') return letter | |
return getRandomCharacter() | |
}) | |
.join('') | |
if (iterations >= originalText.length) clearInterval(interval) | |
iterations += 1 / 3 // for each letter we iterate 3 times, with you put like 1, it will iterate 1 time for each letter, 1 / 4 will iterate 4 times for each letter etc... | |
}, 30) | |
} | |
useEffect(() => { | |
runOnRender && randomizeLetters() | |
}, [randomizeLetters, runOnRender]) | |
return ( | |
<h1 onMouseOver={randomizeLetters} ref={textRef} className={textStyle({ size, className })}> | |
{children} | |
</h1> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment