# Grain Gradient

> A breathing color field with a soft curved shadow, flowing light and fine film grain, drawn with WebGL.

A softly curved color field with fine film grain. The light and the shadow edge breathe slowly together. Use the control panel to change the palette, the composition, the grain and the speed.

<demo-grain-gradient>



</demo-grain-gradient>

## Installation

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

## Usage

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

<template>
  <section class="relative h-140 overflow-hidden rounded-2xl">
    <GrainGradient
      class="absolute inset-0"
      color-light="#dce5df"
      color-mid="#83b9ad"
      color-dark="#031419"
      :grain="0.32"
      :speed="1"
    />
    <div class="relative z-10">
      <!-- hero content -->
    </div>
  </section>
</template>
```

Give the component or its parent a height. Colors accept three- or six-digit hex values and stay the same in light and dark mode. Without WebGL, a CSS gradient of the same three colors shows instead. Motion pauses offscreen and in hidden tabs. Set `speed` to `0` to stop on the current frame.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        color-light
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#dce5df'
      </code>
    </td>
    
    <td>
      Pale highlight color (hex).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        color-mid
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#83b9ad'
      </code>
    </td>
    
    <td>
      Upper-left wash and diffused edge color (hex).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        color-dark
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#031419'
      </code>
    </td>
    
    <td>
      Deep shadow color (hex).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        angle
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Composition rotation in degrees, -360 to 360.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        position
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Horizontal edge offset, -1 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        curve
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.48
      </code>
    </td>
    
    <td>
      Shadow edge curvature, -1 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        softness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.13
      </code>
    </td>
    
    <td>
      Edge diffusion width, 0.01 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Composition zoom, 0.25 to 3.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        grain
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.32
      </code>
    </td>
    
    <td>
      Film grain strength, 0 to 1. Zero removes the texture.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        grain-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Grain size in CSS pixels, 0.5 to 4.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        seed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Reproducible texture seed, 0 to 100000.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Breathing speed, 0 to 2. At 1 the main cycle lasts about 12 seconds.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the container (sizing, rounding).
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The surface is decorative. It sets `aria-hidden="true"` and ignores pointer events, so put any content in a separate layer.
- With `prefers-reduced-motion: reduce`, the gradient draws one still frame and does not animate.
- Ported from [componentry.fun](https://componentry.dev/docs/components/grain-gradient) by Harsh Jadhav.
