# Decrypted Text

> Hacker-style text that cycles random glyphs before resolving, with flip-board and fade effects, a decoding accent color, looping and cursor-local scrambling.

Text that decrypts itself. Letters cycle through random glyphs and resolve into the real text when it scrolls into view, on hover or on click. Letters can swap in place, roll in like a flip board or brighten out of faint glyphs, and a scramble color eases back to the text color as each letter decodes. With a hover radius, only the letters near the cursor scramble. Pick a preset or tune it in the panel.

<demo-decrypted-text>



</demo-decrypted-text>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/decrypted-text.json"
```

## Usage

```vue
<script setup lang="ts">
  import DecryptedText from '~/components/ui/decrypted-text/DecryptedText.vue';
</script>

<template>
  <DecryptedText
    text="Hacking into the mainframe..."
    animate-on="inViewHover"
    effect="flip"
    :speed="60"
    :sequential="true"
    reveal-direction="center"
    :hover-radius="100"
    scramble-color="#2bb673"
    class="cursor-pointer text-[2rem]"
  />
</template>
```

Scrambled glyphs sit on top of an invisible copy of the real letter, and wide glyphs are squeezed with `scaleX` to fit its width, so the line never reflows while it scrambles — in any typeface.

## Props

<table>
<thead>
  <tr>
    <th>
      Prop
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        text
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      The text to decrypt
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        effect
      </code>
    </td>
    
    <td>
      <code>
        'scramble' | 'flip' | 'fade'
      </code>
    </td>
    
    <td>
      <code>
        'scramble'
      </code>
    </td>
    
    <td>
      Scramble swaps glyphs in place, flip rolls each glyph in vertically and lands the real letter with a soft bounce, fade keeps scrambled glyphs faint and brightens them as they resolve
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scramble-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Color of letters while scrambled; each eases back to the text color as it decodes. Empty keeps the text color
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        50
      </code>
    </td>
    
    <td>
      Time between steps, in ms
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        max-iterations
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      Steps the letters scramble before settling when not sequential. Also how long letters keep scrambling after the cursor passes
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sequential
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Reveal one letter per step instead of all at once
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        reveal-direction
      </code>
    </td>
    
    <td>
      <code>
        'start' | 'end' | 'center' | 'random'
      </code>
    </td>
    
    <td>
      <code>
        'start'
      </code>
    </td>
    
    <td>
      Where the sequential reveal starts. Random uncovers letters in a shuffled order
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        use-original-chars-only
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Scramble using only the letters already in the text
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        characters
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      letters + <code>
        !@#…
      </code>
    </td>
    
    <td>
      The pool of characters used while scrambling
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        animate-on
      </code>
    </td>
    
    <td>
      <code>
        'view' | 'hover' | 'inViewHover' | 'click'
      </code>
    </td>
    
    <td>
      <code>
        'hover'
      </code>
    </td>
    
    <td>
      What starts the decryption. View and click start scrambled, so the real text never flashes first
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        click-mode
      </code>
    </td>
    
    <td>
      <code>
        'once' | 'toggle'
      </code>
    </td>
    
    <td>
      <code>
        'once'
      </code>
    </td>
    
    <td>
      With click, decrypt once or toggle back and forth
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hover-radius
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      With hover, only letters within this many px of the cursor scramble, fading toward the edge. <code>
        0
      </code>
      
       decrypts the whole text on hover
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        loop
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      After decrypting, hold, scramble again and repeat. Pauses while off screen
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        loop-delay
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2000
      </code>
    </td>
    
    <td>
      How long the decrypted text holds before scrambling again, in ms
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        revealed-class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Classes for revealed letters
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        encrypted-class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Classes for letters that are still scrambled
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Classes merged onto the wrapper
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The real text lives in a visually hidden span; the scrambling letters are `aria-hidden`, so screen readers always read the final text.
- When the user prefers reduced motion, every trigger reveals the text immediately and hover scrambling is off.
- The flip effect uses the Web Animations API and is skipped under reduced motion.
- Ported from [React Bits](https://reactbits.dev/text-animations/decrypted-text) by David Haz.
