Text Scramble Override

Copy component

Text Scramble Override

Copy component

Nandi Muzsik

How can I improve Framer Uni?

Let me know if there’s a missing feature or something that could be improved.

Share feedback

Nandi Muzsik

How can I improve Framer Uni?

Let me know if there’s a missing feature or something that could be improved.

Share feedback

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.

image of Nandi Muzsik

Created by

Encrypted text override
Encrypted text override
Encrypted text override

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}
            />
        )
    }
}

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

More resources

More resources

  • Interactive Isometric 3D Hero

    Interactive Isometric 3D Hero

    Effect

    Interactive Isometric 3D Hero

    Interactive Isometric 3D Hero

    Effect

    Interactive Isometric 3D Hero

    Interactive Isometric 3D Hero

    Effect

  • Show Once Code Override for Framer

    Show Once Code Override for Framer

    Effect

    Show Once Code Override for Framer

    Show Once Code Override for Framer

    Effect

    Show Once Code Override for Framer

    Show Once Code Override for Framer

    Effect