# Gradient Blinds

> Satin gradient blinds lit by a spotlight that follows the cursor, swaying and turning toward the light.

Gradient blinds drawn in one raw WebGL2 pass. A spotlight follows the cursor on a soft spring and the blinds near it turn toward the light. When the cursor leaves, the light drifts on its own while the blinds sway as if in a breeze. Click to send a wave of light through the blinds, slat to slat.

<demo-gradient-blinds>



</demo-gradient-blinds>

## Installation

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

## Usage

```vue
<script setup lang="ts">
  import GradientBlinds from '~/components/ui/gradient-blinds/GradientBlinds.vue';
</script>

<template>
  <div class="relative h-125 w-full overflow-hidden">
    <GradientBlinds
      :gradient-colors="['#FF9FFC', '#5227FF']"
      :angle="20"
      :blind-count="16"
      :blind-min-width="60"
      :shine="0.4"
      :relief="0.5"
      :sway="0.35"
      click-effect="ripple"
      idle="drift"
    />
  </div>
</template>
```

Pass `light-mode` on a white page. The blinds are then drawn as colored light on white, and `mix-blend-mode` is not applied.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        gradient-colors
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      <code>
        ['#FF9FFC', '#5227FF']
      </code>
    </td>
    
    <td>
      Colors of the gradient across the blinds, up to 8. One color fills every blind.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        angle
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Rotation of the blinds in degrees. 0 stands them upright.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        blind-count
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        16
      </code>
    </td>
    
    <td>
      Number of blinds. Acts as an upper limit when <code>
        blind-min-width
      </code>
      
       is set.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        blind-min-width
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        60
      </code>
    </td>
    
    <td>
      Narrowest a blind can get, in px. Small screens draw fewer blinds.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        shine-direction
      </code>
    </td>
    
    <td>
      <code>
        'left' | 'right'
      </code>
    </td>
    
    <td>
      <code>
        'left'
      </code>
    </td>
    
    <td>
      Which edge of each blind catches the light.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#ffffff'
      </code>
    </td>
    
    <td>
      Color of the light that falls on the blinds.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        spotlight-radius
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Size of the light around the cursor, relative to the area.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        spotlight-softness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How the light fades toward its edge. Higher stays bright longer.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        spotlight-opacity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Strength of the light.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        shine
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.4
      </code>
    </td>
    
    <td>
      Highlight along the lit edge of each blind, from 0 (matte) to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        relief
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Shadow depth where each blind tucks under the next, from 0 (flat) to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glow
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.4
      </code>
    </td>
    
    <td>
      Haze of colored light around the cursor.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sway
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.35
      </code>
    </td>
    
    <td>
      How much the blinds drift and turn on their own.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Speed of the sway and of the drifting light.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hover-tilt
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.6
      </code>
    </td>
    
    <td>
      How much the blinds near the cursor turn toward the light, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        click-effect
      </code>
    </td>
    
    <td>
      <code>
        'ripple' | 'none'
      </code>
    </td>
    
    <td>
      <code>
        'ripple'
      </code>
    </td>
    
    <td>
      Clicking sends a wave of light outward through the blinds.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        idle
      </code>
    </td>
    
    <td>
      <code>
        'drift' | 'center' | 'stay'
      </code>
    </td>
    
    <td>
      <code>
        'drift'
      </code>
    </td>
    
    <td>
      What the light does while the cursor is away.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        perspective
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Makes the blinds recede to one side, from -1 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        gradient-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Drifts the colors across the blinds over time. 0 keeps them still.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mirror-gradient
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Runs the gradient forward and back again.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        distort-amount
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Bends the blinds into soft waves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        noise
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.3
      </code>
    </td>
    
    <td>
      Film grain strength, from 0 (clean) to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-dampening
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.15
      </code>
    </td>
    
    <td>
      Seconds the light takes to catch up with the cursor. 0 follows instantly.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Fades the light in while the blinds turn into place on mount.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        paused
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Freezes the current frame.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mix-blend-mode
      </code>
    </td>
    
    <td>
      <code>
        CSSProperties['mixBlendMode']
      </code>
    </td>
    
    <td>
      <code>
        'lighten'
      </code>
    </td>
    
    <td>
      Blend mode over the page in dark mode, so dark areas show the page behind.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Draws the blinds as colored light on a white page.
    </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 decorative and marked `aria-hidden="true"`. Put real content on top of it.
- With `prefers-reduced-motion: reduce` the blinds hold still: no intro, no sway, no drifting light and no click waves. The light still follows the cursor.
- Pointer tracking is passive and never blocks scrolling or clicks on content above the blinds.
- Animation stops when the blinds are offscreen, the tab is hidden, or nothing is moving.
- Ported from [React Bits](https://reactbits.dev/backgrounds/gradient-blinds) by David Haz.
