Skip to content

Instantly share code, notes, and snippets.

@netgfx
Created November 28, 2022 16:56
Show Gist options
  • Save netgfx/5133fa53eb76b324b086359254b6d64c to your computer and use it in GitHub Desktop.
Save netgfx/5133fa53eb76b324b086359254b6d64c to your computer and use it in GitHub Desktop.
Framer Scramble text
import React from "react"
import { useInterval } from "usehooks-ts"
export const ScrambleText = (props) => {
const { children, size } = props
if (typeof children !== "string")
throw new Error("Children of scramble text must be a single string")
const [scrambledText, setScrambledText] = React.useState(
scrambleText(children.slice(0, size))
)
const [windowStart, increment] = React.useReducer((state) => state + 1, 0)
const finished = windowStart > children.length
useInterval(() => increment(), finished ? null : 30)
useInterval(
() => {
const finishedText = children.slice(0, windowStart)
const scrambled = scrambleText(
children.slice(windowStart, windowStart + size)
)
setScrambledText(finishedText + scrambled)
},
finished ? null : 30
)
return <span>{scrambledText}</span>
}
const scrambleText = (text) => {
const chars = text.split("")
const scrambledChars = chars.map((char) => {
// Don't scramble whitespace
if (/^\s$/.test(char)) {
return char
}
const randomIndex = Math.floor(Math.random() * alphanumericChars.length)
return alphanumericChars[randomIndex]
})
return scrambledChars.join("")
}
// We randomly take characters from this list
const alphanumericChars = [
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"@",
"#",
"$",
"%",
"&",
"*",
"+",
"-",
".",
"/",
":",
";",
"<",
"=",
">",
"?",
"[",
"]",
"{",
"}",
"(",
")",
]
// Styles are written in object syntax
// Learn more: https://reactjs.org/docs/dom-elements.html#style
const containerStyle = {
height: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
overflow: "hidden",
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment