Scroll Down to See
the Scramble Effect

Building clarity through thoughtful user experiences

Simple Scramble
On Scroll Enter

████████████████████████████████████

█████████████████████████████████

1. CDN Scripts

Add these to your <head> or before closing </body> tag:

<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/ScrambleTextPlugin.min.js"></script>

2. Required CSS

[data-scramble-text] {
position: sticky;
top: 50%;
transform: translateY(-50%);
z-index: 10;
pointer-events: none;
}

.scramble-container {
position: relative;
width: 100%;
}

.scramble-section {
height: 100vh;
width: 100%;
position: relative;
}

.scramble-text-wrapper {
position: absolute;
inset: 0;
z-index: 10;
display: flex;
align-items: center;
padding: 0 4vw;
pointer-events: none;
}

3. JavaScript - Multi-Section Scroll Scramble

This version changes text as you scroll through different sections:

gsap.registerPlugin(ScrollTrigger, ScrambleTextPlugin);

document.addEventListener("DOMContentLoaded", () => {
// Multi-section scroll scramble
document.querySelectorAll("[data-scramble-container]").forEach((container) => {
const textElement = container.querySelector("[data-scramble-text]");
if (!textElement) return;

const texts = JSON.parse(container.dataset.scrambleTexts || "[]");
const chars = container.dataset.scrambleChars || "!<>-_\\/[]{}—=+*^?#________";
const duration = parseFloat(container.dataset.scrambleDuration) || 0.5;
const speed = parseFloat(container.dataset.scrambleSpeed) || 0.1;

let currentIndex = 0;

const scrambleTo = (newIndex) => {
if (newIndex === currentIndex || !texts[newIndex]) return;
currentIndex = newIndex;

gsap.to(textElement, {
duration: duration,
scrambleText: {
text: texts[newIndex],
chars: chars,
revealDelay: 0.1,
speed: speed,
},
});
};

// Create triggers for each section
container.querySelectorAll("[data-scramble-trigger]").forEach((section) => {
const index = parseInt(section.dataset.scrambleTrigger);

ScrollTrigger.create({
trigger: section,
start: "top 50%",
onEnter: () => scrambleTo(index),
onLeaveBack: () => scrambleTo(Math.max(0, index - 1)),
});
});
});
});

4. JavaScript - Simple Single Element Scramble

This version scrambles text once when the element enters the viewport:

// Single element scramble on scroll enter
document.querySelectorAll("[data-scramble-single]").forEach((element) => {
const finalText = element.dataset.scrambleFinal || element.textContent;
const chars = element.dataset.scrambleChars || "!<>-_\\/[]{}—=+*^?#";
const duration = parseFloat(element.dataset.scrambleDuration) || 0.5;

ScrollTrigger.create({
trigger: element,
start: "top 80%",
once: true,
onEnter: () => {
gsap.to(element, {
duration: duration,
scrambleText: {
text: finalText,
chars: chars,
revealDelay: 0.1,
speed: 0.1,
},
});
},
});
});

5. HTML Usage - Multi-Section

<!-- Container with text array -->
<div
data-scramble-container
data-scramble-texts='["First text", "Second text", "Third text"]'
data-scramble-chars="▙▚▞▝▀▖▜▛▟"
data-scramble-duration="0.5"
>
<!-- Sticky text element -->
<div class="scramble-text-wrapper">
<p data-scramble-text>First text</p>
</div>

<!-- Trigger sections -->
<section data-scramble-trigger="0">...</section>
<section data-scramble-trigger="1">...</section>
<section data-scramble-trigger="2">...</section>
</div>

6. HTML Usage - Simple Single Element

<!-- Scrambles once when scrolled into view -->
<h2
data-scramble-single
data-scramble-final="Your final revealed text"
data-scramble-chars="!@#$%^&*"
data-scramble-duration="1"
>
████████████████████████
</h2>

7. Data Attributes Reference

AttributeDefaultDescription
data-scramble-containerrequiredWrapper for multi-section scramble
data-scramble-texts[]JSON array of texts to cycle through
data-scramble-textrequiredThe element that displays scrambling text
data-scramble-triggerrequiredIndex of text to show (0, 1, 2...)
data-scramble-single-Enables single-element scramble
data-scramble-finalelement textFinal text to reveal
data-scramble-chars!<>-_\\/[]{}—=+*^?#Characters used during scramble
data-scramble-duration0.5Animation duration in seconds
data-scramble-speed0.1Speed of character reveal

8. Webstudio Implementation

Webstudio Tip: In Webstudio, add the data attributes directly to your elements using the Settings panel. Add the JavaScript in a Custom Code embed or in Project Settings → Custom Code → Footer.

Steps for Webstudio:

1. Add GSAP scripts in Project Settings → Custom Code → Head:
- https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js
- https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/ScrollTrigger.min.js
- https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/ScrambleTextPlugin.min.js

2. Create your HTML structure with Box elements

3. Add data attributes via Settings panel:
- Select the container Box → Settings → Add attribute
- Name: data-scramble-container
- Value: (leave empty)

4. For data-scramble-texts, add as attribute:
- Name: data-scramble-texts
- Value: ["Text 1", "Text 2", "Text 3"]

5. Add the JavaScript in Custom Code embed or Footer

9. Popular Scramble Character Sets

/* Blocks/Unicode */
"▙ ▚ ▞ ▝ ▀ ▖ ▜ ▛ ▟"

/* Matrix-style */
"!<>-_\\/[]{}—=+*^?#"

/* Simple symbols */
"!@#$%^&*()"

/* Letters */
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

/* Numbers */
"0123456789"

/* Mixed */
"▙▚▞akiedzek▝▀▖▜▛▟"