# Pixel Blast

> Dithered pixel clouds that drift, shimmer and light up under the cursor, with ripples, shapes and a perspective floor.

Dithered pixel clouds that drift and shimmer on raw WebGL2. The pixels blast out from the center on mount, the cursor lights up the pixels around it, and every click sends a ring of pixels across the area. Pick from six pixel shapes, or tilt the pattern back into a perspective floor.

<demo-pixel-blast>



</demo-pixel-blast>

## Installation

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

## Usage

```vue
<script setup lang="ts">
  import PixelBlast from '~/components/ui/pixel-blast/PixelBlast.vue';
</script>

<template>
  <div class="relative h-125 w-full overflow-hidden">
    <PixelBlast
      variant="circle"
      color="#7DD3FC"
      accent-color="#E0F2FE"
      :pixel-size="7"
      :pixel-size-jitter="0.5"
      hover-effect="grow"
      :auto-ripple="2"
    />
  </div>
</template>
```

The component fills its parent. The pattern lives in a small grid of cells that is simulated once per frame and then dithered with an 8×8 Bayer matrix at full resolution. Rendering stops when the animation goes quiet, when the tab is hidden, and while the background is scrolled out of view.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#B497CF'
      </code>
    </td>
    
    <td>
      Color of the pixels.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        accent-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        color
      </code>
    </td>
    
    <td>
      Color the densest areas, ripples and the area under the cursor shift toward.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        variant
      </code>
    </td>
    
    <td>
      <code>
        'square' | 'circle' | 'triangle' | 'diamond' | 'cross' | 'ring'
      </code>
    </td>
    
    <td>
      <code>
        'square'
      </code>
    </td>
    
    <td>
      Shape of each pixel.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pixel-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3
      </code>
    </td>
    
    <td>
      Size of each pixel, in px.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pattern-scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2
      </code>
    </td>
    
    <td>
      Zoom of the cloud pattern. Higher values make smaller, busier clouds.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pattern-density
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How many pixels light up. Higher values fill more of the area.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pixel-size-jitter
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Random size variation between pixels, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        softness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.6
      </code>
    </td>
    
    <td>
      Lets pixels grow and shrink smoothly as the pattern moves, instead of popping on and off.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        smoothing
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Smooths the edges of the clouds. 0 keeps the original blocky steps.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glow
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.4
      </code>
    </td>
    
    <td>
      Soft light behind the densest areas, and a hot core in ripples.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        twinkle
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.25
      </code>
    </td>
    
    <td>
      Lets pixels shimmer at their own pace, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      How fast the clouds change shape.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        drift
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.2
      </code>
    </td>
    
    <td>
      How fast the clouds slide across the area. 0 keeps them in place.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        drift-angle
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        30
      </code>
    </td>
    
    <td>
      Direction of the drift, in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hover-effect
      </code>
    </td>
    
    <td>
      <code>
        'reveal' | 'grow' | 'none'
      </code>
    </td>
    
    <td>
      <code>
        'reveal'
      </code>
    </td>
    
    <td>
      What the cursor does: light up more pixels around it, or make nearby pixels swell and glow.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hover-radius
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        140
      </code>
    </td>
    
    <td>
      Size of the area the cursor affects, in px.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        enable-ripples
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Clicking sends a ring of pixels out from the click.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ripple-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.3
      </code>
    </td>
    
    <td>
      How fast ripples spread.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ripple-thickness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.1
      </code>
    </td>
    
    <td>
      Width of the ripple ring.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ripple-intensity-scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Brightness of ripples.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        auto-ripple
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Sends a ripple from a random spot about this many seconds apart. 0 turns it off.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt-x
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Tilts the pixels back into a floor that fades toward the horizon, in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt-y
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Turns the pixels sideways in perspective, in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        edge-fade
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Fades the pixels out toward the edges, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Blasts the pixels out from the center in a ring on mount.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        noise-amount
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Film grain on the pixels.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        transparent
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Shows the page behind the pixels. Off draws a solid black (white in light mode) backdrop.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Darkens hot pixels instead of brightening them, for light pages.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        variation
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      random
    </td>
    
    <td>
      Picks a fixed pattern. Leave it out for a different one on every mount.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        auto-pause-offscreen
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Stops rendering while the background is scrolled out of view.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        dpr
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      auto
    </td>
    
    <td>
      Maximum device pixel ratio, capped at 2.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the container.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The canvas is `aria-hidden`; the container carries an `aria-label`. Put real content on top of it in your own markup.
- Pointer input is read from `window`, so content layered on top stays fully interactive while the cursor still lights up the pixels.
- With `prefers-reduced-motion: reduce` the pattern holds still: no intro, drift, twinkle or ripples. The cursor highlight still follows the pointer.
- Ported from [React Bits](https://reactbits.dev/backgrounds/pixel-blast) by David Haz.
