Example
This is an encrypted text
Installation
Copy and paste the source code into your project.
"use client";
import React, { useRef, useState } from "react";
import { motion } from "framer-motion";
import { cn } from "@/lib/utils";
interface EncryptionTextProps {
children: string;
randomizeOrder?: boolean;
cycles?: number; // New prop to control the number of cycles
shuffleTime?: number; // New prop to control the shuffle time in milliseconds
className?: string;
}
/**
* Props for the EncryptionText component.
*
*
* @property {string} children - The text to be scrambled on hover.
* @property {boolean} [randomizeOrder=false] - Whether to randomize the order of letter scrambling.
* @property {number} [cycles=2] - Number of cycles each letter undergoes before settling.
* @property {number} [shuffleTime=50] - Time interval in milliseconds between each shuffle cycle.
* @property {string} [className] - Additional CSS classes for custom styling.
*/
export const EncryptionText: React.FC<EncryptionTextProps> = ({
children,
randomizeOrder = false,
cycles = 1,
shuffleTime = 50,
className = "text-black dark:text-white font-mono font-bold uppercase",
}) => {
const intervalRef = useRef<number | null>(null);
const targetText = children;
const chars = "!@#$%^&*():{};|,.<>/?";
const [text, setText] = useState<string>(targetText);
const createRandomOrder = (length: number) => {
const order = Array.from({ length }, (_, i) => i);
for (let i = order.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[order[i], order[j]] = [order[j], order[i]];
}
return order;
};
const scramble = () => {
let pos = 0;
const length = targetText.length;
const order = randomizeOrder
? createRandomOrder(length)
: Array.from({ length }, (_, i) => i);
intervalRef.current = window.setInterval(() => {
const scrambled = targetText
.split("")
.map((char, index) => {
const scrambleIndex = randomizeOrder ? order[index] : index;
if (pos / cycles > scrambleIndex) {
return char;
}
const randomCharIndex = Math.floor(Math.random() * chars.length);
const randomChar = chars[randomCharIndex];
return randomChar;
})
.join("");
setText(scrambled);
pos++;
if (pos >= length * cycles) {
stopScramble();
}
}, shuffleTime);
};
const stopScramble = () => {
window.clearInterval(intervalRef.current || undefined);
setText(targetText);
};
return (
<motion.div
onMouseEnter={scramble}
onMouseLeave={stopScramble}
className={cn(className)}
>
<div>{text}</div>
</motion.div>
);
};
Update the import paths to match your project setup.
Props
Prop | Type | Default | Description |
---|---|---|---|
children | string | - | The text content to display. |
randomizeOrder | boolean | false | Whether to randomize the order of letter scrambling. |
cycles | number | 2 | Number of cycles each letter undergoes before settling. |
shuffleTime | number | 50 | Time interval in milliseconds between each shuffle cycle. |
className | string | text-black dark:text-white font-mono font-bold uppercase | Additional CSS classes for custom styling. |