# ASCII Text

> Waving ASCII text that tilts toward the pointer, scrambles on hover and ripples on click.

Text drawn as a grid of ASCII characters by a single WebGL2 shader, so the letters and the coloured blocks under them never drift apart. The word waves, sways and decodes out of random characters on load. Move the pointer to tilt it and spin its hue, hover to scramble the characters near the cursor, and click to send a ring of characters across the canvas. Pick a preset or tune every value in the panel.

<demo-ascii-text>



</demo-ascii-text>

## Installation

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

## Usage

The component fills its nearest positioned parent (`absolute inset-0`), so give that parent a height.

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

<template>
  <div class="relative h-110 w-full overflow-hidden">
    <ASCIIText
      text="Hey!"
      :ascii-font-size="8"
      :colors="['#ff6188', '#fc9867', '#ffd866']"
      :blocks="0.9"
      :scramble="0.6"
      theme="dark"
    />
  </div>
</template>
```

Presets from the demo ship with the component:

```ts
import { asciiTextPreset } from '~/components/ui/ascii-text';

const terminal = asciiTextPreset('terminal'); // classic | terminal | blocks | binary | mono
```

## 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>
      <code>
        'Hey!'
      </code>
    </td>
    
    <td>
      Text rendered in ASCII
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ascii-font-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        8
      </code>
    </td>
    
    <td>
      Height of each character cell in px. Smaller cells give more detail
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        charset
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ' .'`^",:;Il!i~+_-?][}{1)(…'
      </code>
    </td>
    
    <td>
      Characters from darkest to brightest. Unicode blocks work too
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        colors
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      <code>
        ['#ff6188', '#fc9867', '#ffd866']
      </code>
    </td>
    
    <td>
      Character gradient from the center outward, up to three colors
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        text-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#fdf9f3'
      </code>
    </td>
    
    <td>
      Color of the text behind the characters
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        font-family
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'IBM Plex Mono', ui-monospace, …
      </code>
    </td>
    
    <td>
      Font for the text and the characters
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        font-weight
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        600
      </code>
    </td>
    
    <td>
      Weight of the rendered text
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        text-scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Size of the text relative to the container (0.1–3)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        blocks
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.9
      </code>
    </td>
    
    <td>
      Opacity of the colored pixel blocks under the characters (0–1)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        waves
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Strength of the wavy motion. <code>
        0
      </code>
      
       keeps the text flat
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        wave-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Speed of the wavy motion
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        chroma
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Amount of color fringing around the letters
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How far the text turns toward the pointer
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hue-shift
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Hue rotation as the pointer circles the text. <code>
        0
      </code>
      
       keeps colors
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scramble
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.6
      </code>
    </td>
    
    <td>
      Size and strength of the scramble under the pointer (0–1)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        click-ripple
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Send a ring of characters across the canvas from each click
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Decode the text out of random characters on load
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        idle
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Sway the text gently when nobody interacts
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        interactive
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      React to the pointer with tilt, hue, scramble and ripples
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        theme
      </code>
    </td>
    
    <td>
      <code>
        'dark' | 'light'
      </code>
    </td>
    
    <td>
      <code>
        'dark'
      </code>
    </td>
    
    <td>
      <code>
        light
      </code>
      
       inverts the colors so the effect works on white pages
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes on the root
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The root has `role="img"` and an `aria-label` equal to `text`, so screen readers read the word, not the characters.
- With `prefers-reduced-motion: reduce` the waves, idle sway and intro decode stop; the text still renders.
- The render loop pauses while the canvas is off screen. Without WebGL2 the plain text is shown instead.
- Ported from [React Bits](https://reactbits.dev/text-animations/ascii-text) by David Haz.
