@omnedia/ngx-light-rays
Version:
A simple component library to create an underwater light ray background effect.
176 lines (139 loc) • 5.33 kB
Markdown
<a href="https://ngxui.com" target="_blank" style="display: flex;gap: .5rem;align-items: center;cursor: pointer; padding: 0 0 0 0; height: fit-content;">
<img src="https://ngxui.com/assets/img/ngxui-logo.png" style="width: 64px;height: 64px;">
</a>
This library is part of the NGXUI ecosystem. <br>
View all available components at [https://ngxui.com](https://ngxui.com)
`@omnedia/ngx-light-rays` is an Angular library that renders animated, shader-driven light rays. It supports configurable origin, color, speed, spread, length, pulsation, and optional mouse-follow, producing cinematic volumetric streaks that work great as a dynamic background or hero accent.
* WebGL shader-based **light rays** with high performance.
* **Configurable origin** (top/left/right/bottom variants).
* **Color, speed, spread, length, pulsation**, noise and distortion controls.
* **Optional mouse-follow** with adjustable influence.
* Renders only when visible via **IntersectionObserver** for efficiency.
* Standalone Angular 20+ component.
```bash
npm install @omnedia/ngx-light-rays ogl
```
Import the `NgxLightRaysComponent` into your component:
```ts
import {Component} from '@angular/core';
import {NgxLightRaysComponent} from '@omnedia/ngx-light-rays';
@Component({
selector: 'app-hero',
standalone: true,
imports: [NgxLightRaysComponent],
template: `
<section class="hero">
<om-light-rays
[]="'top-center'"
[]="'#ffffff'"
[]="1"
[]="1"
[]="2"
[]="false"
[]="1.0"
[]="1.0"
[]="false"
[]="0.1"
[]="0.05"
[]="0.0"
styleClass="rays"
></om-light-rays>
</section>
`,
styles: [
`.hero{ position:relative; height:480px; }`,
`om-light-rays, .rays{ position:absolute; inset:0; display:block; }`
]
})
export class HeroComponent {
}
```
The component attaches a WebGL canvas and runs a fragment shader that accumulates ray intensity from a configurable origin. It updates only when in view and adapts to container size/scale. Optional mouse-follow adjusts the ray direction smoothly using a smoothed pointer position.
```html
<om-light-rays
[]="raysOrigin"
[]="raysColor"
[]="raysSpeed"
[]="lightSpread"
[]="rayLength"
[]="pulsating"
[]="fadeDistance"
[]="saturation"
[]="followMouse"
[]="mouseInfluence"
[]="noiseAmount"
[]="distortion"
[]="styleClass"
></om-light-rays>
```
* `raysOrigin` (`RaysOrigin`, default `'top-center'`):
`"top-center" | "top-left" | "top-right" | "right" | "left" | "bottom-center" | "bottom-right" | "bottom-left"`.
* `raysColor` (`string`, default `'#ffffff'`): Hex CSS color.
* `raysSpeed` (`number`, default `1`): Animation speed multiplier.
* `lightSpread` (`number`, default `1`): Beam spread; higher values tighten the rays.
* `rayLength` (`number`, default `2`): Effective length scale of rays.
* `pulsating` (`boolean`, default `false`): Enables subtle pulsing.
* `fadeDistance` (`number`, default `1.0`): Additional fade falloff distance scale.
* `saturation` (`number`, default `1.0`): Color saturation mix (0 = grayscale, 1 = original).
* `followMouse` (`boolean`, default `false`): Enable mouse-follow behavior.
* `mouseInfluence` (`number`, default `0.1`): Mix factor toward mouse direction when `followMouse` is true.
* `noiseAmount` (`number`, default `0.0`): Grain noise intensity.
* `distortion` (`number`, default `0.0`): Angular distortion amount (subtle wavy rays).
* `styleClass` (`string`, optional): Custom CSS class applied to the container.
## Examples
**Hero accent with subtle movement**
```html
<om-light-rays
[raysOrigin]="'top-left'"
[]="'#d2e7ff'"
[]="0.7"
[]="1.2"
[]="2.5"
[]="true"
[]="1.2"
[]="0.9"
[]="false"
[]="0.03"
styleClass="cover"
></om-light-rays>
```
**Interactive spotlight**
```html
<om-light-rays
[]="'left'"
[]="'#ffffff'"
[]="true"
[]="0.2"
[]="3"
[]="0.9"
styleClass="cover"
></om-light-rays>
```
The component injects a canvas that fills its host container. Style the host or pass `styleClass` to position/size.
```css
.cover {
position: absolute;
inset: 0;
display: block;
}
om-light-rays {
display: block;
}
```
> **Tip:** Ensure the host element has an explicit height (e.g., via parent layout) so the canvas has space to render.
## Performance
* Rendering is paused when the element is not visible (IntersectionObserver).
* DPR is capped for efficiency.
* Use lower `noiseAmount`/`distortion` for extra performance headroom.
## Contributing
Contributions are welcome. Please open an issue or PR.
## License
MIT License.