Skip to content

Instantly share code, notes, and snippets.

@DarlonHenrique
Last active August 20, 2023 20:55
Show Gist options
  • Save DarlonHenrique/2910dc561d751d84b9c7980a7e20f19c to your computer and use it in GitHub Desktop.
Save DarlonHenrique/2910dc561d751d84b9c7980a7e20f19c to your computer and use it in GitHub Desktop.
component with cool hacker effect in the letters
'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