color-decoder
v0.0.1
Published
An Angular directive that detects the color beneath its host element (from an ancestor/sibling `<video>` or `<img>`) and emits the **complementary (inverted) color** — perfect for keeping overlaid text readable on dynamic backgrounds.
Readme
Color Decoder
An Angular directive that detects the color beneath its host element (from an ancestor/sibling <video> or <img>) and emits the complementary (inverted) color — perfect for keeping overlaid text readable on dynamic backgrounds.
Features
- 🎨 Real-time color sampling from
<video>or<img>elements - 🔄 Complementary color output so overlaid content stays visible
- ⚡ Optimised rendering — samples only a 1×1 pixel region, not the full frame
- 🎯 Auto-apply mode — optionally sets the host element's CSS
colorautomatically - ⏱️ Configurable sample rate to balance smoothness vs. CPU usage
- 🧠 Smart source discovery — walks the DOM to find the nearest visual source
Installation
npm install color-decoderPeer Dependencies
| Package | Version |
| ---------------- | --------- |
| @angular/core | ^21.2.0 |
| @angular/common| ^21.2.0 |
Usage
Basic — listen for color changes
import { Component } from '@angular/core';
import { ColorDecoder } from 'color-decoder';
@Component({
selector: 'app-video-overlay',
imports: [ColorDecoder],
template: `
<div class="video-wrapper">
<video src="clip.mp4" autoplay muted loop></video>
<p colorDecoder (colorDecoded)="textColor = $event"
[style.color]="textColor">
Readable overlay text
</p>
</div>
`,
})
export class VideoOverlayComponent {
textColor = '#ffffff';
}Auto-apply mode
Skip the manual binding — the directive sets color on the host element for you:
<p colorDecoder [autoApply]="true" (colorDecoded)="onColor($event)">
Text color updates automatically
</p>Custom sample interval
Control how often the pixel is sampled (default: 200 ms):
<p colorDecoder [sampleInterval]="100" [autoApply]="true">
Smoother updates (higher CPU)
</p>API Reference
Selector
[colorDecoder]
Inputs
| Input | Type | Default | Description |
| ---------------- | --------- | ------- | -------------------------------------------------------- |
| autoApply | boolean | false | Automatically set the host element's CSS color |
| sampleInterval | number | 200 | Minimum milliseconds between consecutive pixel samples |
Outputs
| Output | Type | Description |
| -------------- | -------- | ---------------------------------------------------- |
| colorDecoded | string | Emits the complementary hex color (e.g. #00ffff) |
Exported Utilities
The library also exports pure helper functions you can use independently:
import {
invertRgb,
rgbToHex,
findVisualSource,
samplePixelAt,
mapToSourceCoords,
} from 'color-decoder';| Function | Description |
| ------------------- | ----------------------------------------------------------------- |
| invertRgb(r,g,b) | Returns the complementary [r, g, b] triplet |
| rgbToHex(r,g,b) | Converts an RGB triplet to a #rrggbb hex string |
| findVisualSource | Walks up the DOM to find the nearest <video> or <img> |
| samplePixelAt | Samples a single pixel from a media element via a 1×1 canvas |
| mapToSourceCoords | Maps element bounding-box coords to the source's intrinsic coords |
How It Works
- A
requestAnimationFrameloop runs while the directive is alive. - On each tick (throttled by
sampleInterval) the directive locates the nearest<video>/<img>ancestor or sibling. - It maps the centre of the host element to the media's intrinsic (natural) coordinate space.
- A 1×1 off-screen canvas draws only that single pixel and reads its RGB value.
- The RGB value is inverted to produce the complementary color and emitted via
colorDecoded.
Browser Support
Works in all modern browsers. Uses OffscreenCanvas where available, with a <canvas> fallback.
License
MIT © Omdevsinh007
