Effect
Text Scramble Override
This is a code override that you can apply to any text layer to achieve this text scramble effect. Can be a nice little detail on your websites, however, make sure not to overuse it.
Created by
About the resource
When applying this code override for your text layer, you can choose between "onAppear" and "onLoop".
On appear will show the text scramble effect on page load, and on loop will play the scramble animation over and over again (forever).
Code override
You can copy the code override below and paste it in Framer to achieve the text scramble effect.
About the resource
When applying this code override for your text layer, you can choose between "onAppear" and "onLoop".
On appear will show the text scramble effect on page load, and on loop will play the scramble animation over and over again (forever).
Code override
You can copy the code override below and paste it in Framer to achieve the text scramble effect.
About the resource
When applying this code override for your text layer, you can choose between "onAppear" and "onLoop".
On appear will show the text scramble effect on page load, and on loop will play the scramble animation over and over again (forever).
Code override
You can copy the code override below and paste it in Framer to achieve the text scramble effect.
// © Framer University. All rights reserved.
import type { ComponentType } from "react"
import { useEffect, useState, useRef } from "react"
// Loop only
const loopDelay = 1000
const initDelay = 100
// Do not configure
const letters = "abcdefghijklmnopqrstuvwxyz-.,+*!?@&%/="
export function onAppear(Component): ComponentType {
return (props) => {
const value = props.children.props.children.props.children
const [isVisible, setIsVisible] = useState(false)
const [iteration, setIteration] = useState(0)
const intersectionRef = useRef(null)
const encrypt = (iteration: number) => {
return value
.split("")
.map((letter, index) => {
if (index < iteration) {
return value[index]
}
return letters[Math.floor(Math.random() * 38)]
})
.join("")
}
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setIsVisible(true)
} else {
setIsVisible(false)
}
})
})
observer.observe(intersectionRef.current)
return () => observer.disconnect()
}, [])
useEffect(() => {
let interval = null
if (isVisible) {
interval = setTimeout(() => {
setIteration((prev) => prev + 5 / 6)
interval = setInterval(() => {
setIteration((prev) => prev + 5 / 6)
}, 50)
}, 100)
}
return () => clearInterval(interval)
}, [isVisible])
return (
<Component
ref={intersectionRef}
{...props}
text={isVisible ? encrypt(iteration) : value}
/>
)
}
}
export function onLoop(Component): ComponentType {
return (props) => {
const value = props.children.props.children.props.children
const [isVisible, setIsVisible] = useState(false)
const [iteration, setIteration] = useState(0)
const [delayTime, setDelayTime] = useState(loopDelay)
const intersectionRef = useRef(null)
const encrypt = (iteration: number) => {
const length = value.length
let result = ""
for (let i = 0; i < length; i++) {
const letter = value[i]
if (i < iteration) {
result += letter
} else {
result += letters[Math.floor(Math.random() * 38)]
}
}
if (iteration >= length) {
setTimeout(() => {
setIteration(0)
}, delayTime)
}
return result
}
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setIsVisible(true)
} else {
setIsVisible(false)
}
})
})
observer.observe(intersectionRef.current)
return () => observer.disconnect()
}, [])
useEffect(() => {
let interval = null
if (isVisible) {
interval = setTimeout(() => {
setIteration((prev) => prev + 5 / 6)
interval = setInterval(() => {
setIteration((prev) => prev + 5 / 6)
}, 50)
}, initDelay)
}
return () => clearInterval(interval)
}, [isVisible])
return (
<Component
ref={intersectionRef}
{...props}
text={isVisible ? encrypt(iteration) : value}
/>
)
}
}
// © Framer University. All rights reserved.
import type { ComponentType } from "react"
import { useEffect, useState, useRef } from "react"
// Loop only
const loopDelay = 1000
const initDelay = 100
// Do not configure
const letters = "abcdefghijklmnopqrstuvwxyz-.,+*!?@&%/="
export function onAppear(Component): ComponentType {
return (props) => {
const value = props.children.props.children.props.children
const [isVisible, setIsVisible] = useState(false)
const [iteration, setIteration] = useState(0)
const intersectionRef = useRef(null)
const encrypt = (iteration: number) => {
return value
.split("")
.map((letter, index) => {
if (index < iteration) {
return value[index]
}
return letters[Math.floor(Math.random() * 38)]
})
.join("")
}
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setIsVisible(true)
} else {
setIsVisible(false)
}
})
})
observer.observe(intersectionRef.current)
return () => observer.disconnect()
}, [])
useEffect(() => {
let interval = null
if (isVisible) {
interval = setTimeout(() => {
setIteration((prev) => prev + 5 / 6)
interval = setInterval(() => {
setIteration((prev) => prev + 5 / 6)
}, 50)
}, 100)
}
return () => clearInterval(interval)
}, [isVisible])
return (
<Component
ref={intersectionRef}
{...props}
text={isVisible ? encrypt(iteration) : value}
/>
)
}
}
export function onLoop(Component): ComponentType {
return (props) => {
const value = props.children.props.children.props.children
const [isVisible, setIsVisible] = useState(false)
const [iteration, setIteration] = useState(0)
const [delayTime, setDelayTime] = useState(loopDelay)
const intersectionRef = useRef(null)
const encrypt = (iteration: number) => {
const length = value.length
let result = ""
for (let i = 0; i < length; i++) {
const letter = value[i]
if (i < iteration) {
result += letter
} else {
result += letters[Math.floor(Math.random() * 38)]
}
}
if (iteration >= length) {
setTimeout(() => {
setIteration(0)
}, delayTime)
}
return result
}
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setIsVisible(true)
} else {
setIsVisible(false)
}
})
})
observer.observe(intersectionRef.current)
return () => observer.disconnect()
}, [])
useEffect(() => {
let interval = null
if (isVisible) {
interval = setTimeout(() => {
setIteration((prev) => prev + 5 / 6)
interval = setInterval(() => {
setIteration((prev) => prev + 5 / 6)
}, 50)
}, initDelay)
}
return () => clearInterval(interval)
}, [isVisible])
return (
<Component
ref={intersectionRef}
{...props}
text={isVisible ? encrypt(iteration) : value}
/>
)
}
}
// © Framer University. All rights reserved.
import type { ComponentType } from "react"
import { useEffect, useState, useRef } from "react"
// Loop only
const loopDelay = 1000
const initDelay = 100
// Do not configure
const letters = "abcdefghijklmnopqrstuvwxyz-.,+*!?@&%/="
export function onAppear(Component): ComponentType {
return (props) => {
const value = props.children.props.children.props.children
const [isVisible, setIsVisible] = useState(false)
const [iteration, setIteration] = useState(0)
const intersectionRef = useRef(null)
const encrypt = (iteration: number) => {
return value
.split("")
.map((letter, index) => {
if (index < iteration) {
return value[index]
}
return letters[Math.floor(Math.random() * 38)]
})
.join("")
}
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setIsVisible(true)
} else {
setIsVisible(false)
}
})
})
observer.observe(intersectionRef.current)
return () => observer.disconnect()
}, [])
useEffect(() => {
let interval = null
if (isVisible) {
interval = setTimeout(() => {
setIteration((prev) => prev + 5 / 6)
interval = setInterval(() => {
setIteration((prev) => prev + 5 / 6)
}, 50)
}, 100)
}
return () => clearInterval(interval)
}, [isVisible])
return (
<Component
ref={intersectionRef}
{...props}
text={isVisible ? encrypt(iteration) : value}
/>
)
}
}
export function onLoop(Component): ComponentType {
return (props) => {
const value = props.children.props.children.props.children
const [isVisible, setIsVisible] = useState(false)
const [iteration, setIteration] = useState(0)
const [delayTime, setDelayTime] = useState(loopDelay)
const intersectionRef = useRef(null)
const encrypt = (iteration: number) => {
const length = value.length
let result = ""
for (let i = 0; i < length; i++) {
const letter = value[i]
if (i < iteration) {
result += letter
} else {
result += letters[Math.floor(Math.random() * 38)]
}
}
if (iteration >= length) {
setTimeout(() => {
setIteration(0)
}, delayTime)
}
return result
}
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setIsVisible(true)
} else {
setIsVisible(false)
}
})
})
observer.observe(intersectionRef.current)
return () => observer.disconnect()
}, [])
useEffect(() => {
let interval = null
if (isVisible) {
interval = setTimeout(() => {
setIteration((prev) => prev + 5 / 6)
interval = setInterval(() => {
setIteration((prev) => prev + 5 / 6)
}, 50)
}, initDelay)
}
return () => clearInterval(interval)
}, [isVisible])
return (
<Component
ref={intersectionRef}
{...props}
text={isVisible ? encrypt(iteration) : value}
/>
)
}
}