# Echo Text

> Ghosted copies trail behind the text and settle into a single word — cursor-driven, auto-drifting or scroll-driven trails with click bursts.

A stack of tinted, blurred copies sits behind the text. On entrance they slide in and collapse into one word. Move the cursor and the text leans toward it while the echoes lag behind; click the text to send out a burst of expanding echoes. The trail can also drift on its own or stretch behind page scrolling.

<demo-echo-text>



</demo-echo-text>

## Installation

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

## Usage

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

<template>
  <EchoText
    text="Motion Echo"
    :echoes="12"
    :lag="0.24"
    :offset="36"
    direction="right"
    :echo-colors="['currentColor', '#ff7a45']"
    trail="auto"
    :click-burst="true"
  />
</template>
```

## 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>
        'Motion Echo'
      </code>
    </td>
    
    <td>
      Text rendered by the crisp front copy and every echo
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        echoes
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        12
      </code>
    </td>
    
    <td>
      Number of ghost copies behind the front text, up to 24
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        lag
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.24
      </code>
    </td>
    
    <td>
      How slowly deeper echoes catch up, and how far apart they spread along the auto trail
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        offset
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        36
      </code>
    </td>
    
    <td>
      Entrance spread, cursor lean, drift and click-burst reach, in px
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        direction
      </code>
    </td>
    
    <td>
      <code>
        'right' | 'left' | 'up' | 'down' | 'diagonal'
      </code>
    </td>
    
    <td>
      <code>
        'right'
      </code>
    </td>
    
    <td>
      Direction the entrance trail settles in from
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fade
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.72
      </code>
    </td>
    
    <td>
      How much of its opacity each echo keeps from the one in front of it
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        blur
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3
      </code>
    </td>
    
    <td>
      Blur on the deepest echo, in px. Echoes in between blur less
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tint
      </code>
    </td>
    
    <td>
      <code>
        string | false
      </code>
    </td>
    
    <td>
      <code>
        '#7dd3fc'
      </code>
    </td>
    
    <td>
      Color blended into the echoes, stronger toward the back. <code>
        false
      </code>
      
       for plain echoes
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        echo-colors
      </code>
    </td>
    
    <td>
      <code>
        [string, string]
      </code>
    </td>
    
    <td>
      <code>
        undefined
      </code>
    </td>
    
    <td>
      Two colors the echoes fade between, nearest to deepest. Replaces the tint when set
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        echo-style
      </code>
    </td>
    
    <td>
      <code>
        'solid' | 'outline'
      </code>
    </td>
    
    <td>
      <code>
        'solid'
      </code>
    </td>
    
    <td>
      Draws the echoes as filled text or thin outlines
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        echo-scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Size of the deepest echo relative to the text. Below 1 the trail recedes, above 1 it looms
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mode
      </code>
    </td>
    
    <td>
      <code>
        'entrance' | 'pointer' | 'both'
      </code>
    </td>
    
    <td>
      <code>
        'both'
      </code>
    </td>
    
    <td>
      Whether the echoes play on entrance, run the live trail, or both. <code>
        pointer
      </code>
      
       means trail only, whatever drives it
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        trail
      </code>
    </td>
    
    <td>
      <code>
        'pointer' | 'auto' | 'scroll'
      </code>
    </td>
    
    <td>
      <code>
        'pointer'
      </code>
    </td>
    
    <td>
      What drives the live trail: the cursor, a slow figure-eight drift while the cursor is away, or page scrolling
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        click-burst
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Clicking the text releases echoes that expand from the click point and fade
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        cursor-radius
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        320
      </code>
    </td>
    
    <td>
      Distance in px over which the cursor pulls the text to full offset. With <code>
        trail="auto"
      </code>
      
       the drift resumes beyond it
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        duration
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        900
      </code>
    </td>
    
    <td>
      How long the entrance takes to settle, in ms
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ease
      </code>
    </td>
    
    <td>
      <code>
        'linear' | 'ease-out' | 'ease-in-out' | 'snappy'
      </code>
    </td>
    
    <td>
      <code>
        'ease-out'
      </code>
    </td>
    
    <td>
      Timing curve of the entrance
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        font-size
      </code>
    </td>
    
    <td>
      <code>
        string | number
      </code>
    </td>
    
    <td>
      <code>
        'clamp(3rem, 9vw, 7rem)'
      </code>
    </td>
    
    <td>
      Font size of the text (numbers are px)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        font-weight
      </code>
    </td>
    
    <td>
      <code>
        string | number
      </code>
    </td>
    
    <td>
      <code>
        800
      </code>
    </td>
    
    <td>
      Font weight of the text
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'currentColor'
      </code>
    </td>
    
    <td>
      Color of the front copy. Follows the surrounding text color by default
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes on the root element
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- Only the front copy is exposed to assistive technology; every echo and burst copy is `aria-hidden`.
- With `prefers-reduced-motion: reduce` no echoes render and the text stays still.
- The cursor follow only runs on devices with a fine, hovering pointer.
- Ported from [React Bits](https://reactbits.dev/text-animations/echo-text) by David Haz.
