Scramble Text <mv-scramble-text>

디코딩 효과: 화면에 보일 때, 호버나 포커스 시 무작위 글리프가 실제 텍스트로 풀립니다(처음, 끝, 가운데부터 또는 무작위로).

작동 방식

디코딩 효과: 화면에 보일 때, 호버나 포커스 시 무작위 글리프가 실제 텍스트로 풀립니다(처음, 끝, 가운데부터 또는 무작위로). 실제 텍스트는 제자리에 있고 아직 풀리지 않은 문자만 가려지며, 너비를 맞춘 글리프가 정확한 상자 위에 그려지므로 어떤 글꼴에서도 아무것도 움직이지 않습니다. 일반 텍스트처럼 인라인으로 줄바꿈되고, 값이 바뀌면 바뀐 문자만 디코딩합니다.

카테고리애니메이션 텍스트
유형Web Component (<mv-scramble-text>)
상태안정
Keywordsscramble, decrypt, decode, hacker, glitch, hover, hyper-text, shuffle, accessible

When to use

  • A heading or label should decrypt from random glyphs into the real text on view, hover or focus
  • A tech or security brand needs a decode effect that never shifts layout, even in a proportional font or mid-sentence
  • A changing value such as a key, code or status should visibly decode only the characters that changed

Avoid when

  • A recurring RGB-split glitch look is wanted instead of a one-time resolve → use Glitch Text instead
  • Long paragraphs; per-character scrambling slows reading and draws too much attention

설치

node scripts/add.mjs scramble-text --out ./src/marvelous

Marvelous UI MCP 서버를 사용하는 AI 에이전트: install_components({ slugs: ["scramble-text"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

복사되는 파일(의존성 포함): tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/motion.js, core/observe.js, components/scramble-text/scramble-text.js, components/scramble-text/scramble-text.css.

사용법

빠른 시작, 동작하는 가장 작은 마크업:

<h2><mv-scramble-text>Access granted</mv-scramble-text></h2>

기본 마크업입니다. 여기서 시작해 속성, data-*, CSS 변수로 커스터마이즈하세요:

<div id="st-demo" style="display:grid;gap:1.75rem;justify-items:center;text-align:center;width:min(100%,44rem);margin-inline:auto">
  <div style="display:inline-flex;align-items:center;gap:.6rem;padding:.4rem .85rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-full);background:var(--mv-surface);font-size:.8rem;color:var(--mv-fg-muted)">
    <span style="width:.5rem;height:.5rem;border-radius:50%;background:var(--mv-success);box-shadow:0 0 0 3px color-mix(in oklch,var(--mv-success) 25%,transparent)"></span>
    <mv-scramble-text monospace duration="1200" delay="200" style="letter-spacing:.08em">SECURE CHANNEL · AES-256</mv-scramble-text>
  </div>

  <h2 style="margin:0;font:700 clamp(1.9rem,4.6vw,3.2rem)/1.1 var(--mv-font-display);letter-spacing:-.035em">
    <mv-scramble-text reveal="random" duration="1400" trigger="view hover" colors="var(--mv-accent), var(--mv-info), var(--mv-fg-subtle)">Your data, encrypted end to end.</mv-scramble-text>
  </h2>

  <nav aria-label="Demo" style="display:flex;gap:.35rem;flex-wrap:wrap;justify-content:center;font:500 .95rem/1 var(--mv-font-mono);text-transform:uppercase;letter-spacing:.06em">
    <a href="#scramble-text" style="padding:.55rem .8rem;border-radius:var(--mv-radius-md);color:inherit;text-decoration:none;background:var(--mv-bg-muted)"><mv-scramble-text trigger="hover" duration="500">Projects</mv-scramble-text></a>
    <a href="#scramble-text" style="padding:.55rem .8rem;border-radius:var(--mv-radius-md);color:inherit;text-decoration:none;background:var(--mv-bg-muted)"><mv-scramble-text trigger="hover" duration="500">Studio</mv-scramble-text></a>
    <a href="#scramble-text" style="padding:.55rem .8rem;border-radius:var(--mv-radius-md);color:inherit;text-decoration:none;background:var(--mv-bg-muted)"><mv-scramble-text trigger="hover" duration="500">Journal</mv-scramble-text></a>
    <a href="#scramble-text" style="padding:.55rem .8rem;border-radius:var(--mv-radius-md);color:inherit;text-decoration:none;background:var(--mv-bg-muted)"><mv-scramble-text trigger="hover" duration="500" reveal="end">Contact</mv-scramble-text></a>
  </nav>

  <div style="display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;justify-content:center">
    <span style="font-size:.8rem;color:var(--mv-fg-muted)">Deploy key</span>
    <code style="padding:.35rem .6rem;border-radius:var(--mv-radius-sm);background:var(--mv-bg-muted);font-size:.9rem"><mv-scramble-text id="st-demo-key" monospace trigger="manual" duration="700" text="mv_live_7Q4K-92XD-LM0A"></mv-scramble-text></code>
    <button type="button" class="mv-button" data-variant="outline" data-size="sm" id="st-demo-rotate">Rotate key</button>
  </div>

  <p style="margin:0;font-size:.85rem;color:var(--mv-fg-subtle)">Hover or focus the heading and the links to replay; rotating the key decodes only the characters that change.</p>
</div>
<script type="module">
  const key = document.getElementById("st-demo-key");
  const button = document.getElementById("st-demo-rotate");
  const block = () => Array.from({ length: 4 }, () => "ABCDEFGHJKLMNPQRSTUVWXYZ0123456789"[Math.floor(Math.random() * 33)]).join("");
  button?.addEventListener("click", () => {
    const parts = key.text.split("-");
    parts[1 + Math.floor(Math.random() * 2)] = block();
    key.text = parts.join("-");
  });
</script>

API

Attributes

Name유형DefaultDescription
triggerview | load | hover | focus | manualviewCombinable ("view hover"). hover replays on pointer hover (not touch) and on keyboard focus; focus replays on focus only. Hover and focus listen on the closest link, button or focusable ancestor.
durationnumber (ms)900Time until the last character resolves.
speednumber (ms)45How often glyphs change.
delaynumber (ms)0Extra wait before characters start resolving.
revealstart | end | center | randomstartResolution order.
glyphsstringA-Z 0-9 #%&*+=<>…Glyph set (e.g. "01" for binary, katakana…). The default set keeps case and turns digits into digits. Glyphs are picked close in width to each real character.
colorslist of CSS colorsColors picked at random for each glyph.
monospacebooleanMonospace font (terminal look). The width never changes without it either.
textstringTarget text (otherwise the element's text). Setting a new value decodes only the characters that changed.
data-statescrambling | doneSet by the element: scrambling (glyphs showing) or done (real text only).

Methods

NameDescription
play() / replay()Scrambles, then resolves again.

Events

NameDescription
mv-endAll characters have resolved.

CSS classes

NameDescription
mv-scramble-text-text / -glyphs / -charReal text (one plain text node), aria-hidden out-of-flow glyph layer, one glyph box per character on that layer.

CSS variables

NameDefaultDescription
--mv-scramble-text-glyphvar(--mv-accent-fg)Glyph color (also the color of the lock-in echo).

Accessibility

The real text is always one plain, visible text node: screen readers, find-in-page, selection, copy and translation get it unchanged, even mid-animation. Unresolved characters are only masked (a CSS highlight makes them transparent); glyphs live on an aria-hidden, out-of-flow layer (pointer-events none, user-select none) and are painted as generated content with empty alternative text, so they are never read nor found. Each glyph sits on its character’s measured box, so the layout never shifts and kerning is untouched, in any font. With reduced motion (system or data-motion="reduce") or forced colors, the final text shows at once and nothing scrambles. hover also replays on keyboard focus and ignores touch; focus replays on focus only. Printing settles to the real text. The frame loop pauses off-screen and in hidden tabs. Without CSS highlights (older browsers) the real text is hidden as a whole during the effect and the layer draws it, still at the same boxes.

이 페이지는 AI로 번역되었습니다. 번역 문제 신고