React component that replicates YouTube's thumbnail hover effect with dominant color extraction
npm install @nirajrajput-dev/image-dominant-hoverbash
npm install @niraj/image-dominant-hover
`
ð Quick Start
`tsx
import { ImageCard } from "@niraj/image-dominant-hover";
function App() {
return (
src="https://example.com/image.jpg"
alt="Beautiful landscape"
title="Mountain View"
description="A stunning mountain landscape"
/>
);
}
`
ð API Reference
$3
| Prop | Type | Default | Description |
| ------------------------ | --------------------------- | ----------- | ---------------------------------------- |
| src | string | _required_ | Image source URL |
| alt | string | _required_ | Alt text for accessibility |
| title | string | undefined | Optional title displayed below image |
| description | string | undefined | Optional description text |
| width | number \| string | 300 | Card width (px or CSS string) |
| height | number \| string | 180 | Image height (px or CSS string) |
| className | string | "" | Additional CSS classes |
| transitionDuration | number | 300 | Transition duration in milliseconds |
| onClick | () => void | undefined | Click handler (makes card interactive) |
| onColorExtracted | (color: RGBColor) => void | undefined | Callback when color extraction completes |
| onColorExtractionError | (error: Error) => void | undefined | Callback when extraction fails |
$3
`typescript
interface RGBColor {
r: number; // 0-255
g: number; // 0-255
b: number; // 0-255
}
`
ðŊ Usage Examples
$3
`tsx
import { ImageCard } from "@niraj/image-dominant-hover";
;
`
$3
`tsx
src="/images/portrait.jpg"
alt="Portrait photo"
width={400}
height={600}
/>
`
$3
`tsx
src="/images/product.jpg"
alt="Product showcase"
title="Premium Headphones"
description="Experience audio perfection"
onClick={() => console.log("Card clicked!")}
/>
`
$3
`tsx
src="/images/artwork.jpg"
alt="Digital artwork"
onColorExtracted={(color) => {
console.log(Dominant color: rgb(${color.r}, ${color.g}, ${color.b}));
}}
onColorExtractionError={(error) => {
console.error("Color extraction failed:", error);
}}
/>
`
$3
`tsx
src="/images/nature.jpg"
alt="Nature scene"
transitionDuration={500} // Slower transition
/>
`
$3
`tsx
src="/images/banner.jpg"
alt="Banner image"
width="100%"
height="auto"
/>
`
ð ïļ Utility Functions
The library also exports utility functions for advanced use cases:
$3
Extract dominant color from any image URL:
`typescript
import { extractDominantColor } from "@niraj/image-dominant-hover";
const color = await extractDominantColor("https://example.com/image.jpg");
console.log(color); // { r: 128, g: 64, b: 192 }
`
$3
Convert RGB object to CSS string:
`typescript
import { rgbToString } from "@niraj/image-dominant-hover";
const cssColor = rgbToString({ r: 255, g: 128, b: 0 });
console.log(cssColor); // "rgb(255, 128, 0)"
`
$3
Calculate perceived brightness (0-1):
`typescript
import { calculateBrightness } from "@niraj/image-dominant-hover";
const brightness = calculateBrightness({ r: 128, g: 128, b: 128 });
console.log(brightness); // ~0.215 (WCAG relative luminance)
`
$3
`typescript
import { getCacheSize, clearColorCache } from "@niraj/image-dominant-hover";
console.log(getCacheSize()); // Number of cached colors
clearColorCache(); // Clear all cached colors
`
ðĻ Styling
The component uses inline styles by default, but you can customize appearance using the className prop:
`tsx
`
`css
.my-custom-card {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
border: 2px solid #e0e0e0;
}
.my-custom-card:hover {
transform: scale(1.05);
}
`
âïļ How It Works
1. Image Load: Component renders with the provided image
2. Color Extraction: Canvas API samples center region pixels (asynchronously)
3. Caching: Extracted color is cached in memory for instant future use
4. Hover Effect: On hover, background smoothly transitions to the dominant color
5. Performance: Subsequent hovers use cached color (no re-extraction)
$3
- Samples from the center 50% of the image (most representative area)
- Skips transparent, very bright, and very dark pixels (noise reduction)
- Uses pixel averaging for accurate color representation
- Limits canvas size to 200Ã200px for optimal performance
ð Browser Support
- Chrome/Edge: â
Latest 2 versions
- Firefox: â
Latest 2 versions
- Safari: â
iOS 14+, macOS latest 2 versions
- Modern browsers with ES2020+ support
Note: Canvas API and crossOrigin support required for external images.
ð CORS Considerations
For external images, ensure the server sends proper CORS headers:
`
Access-Control-Allow-Origin: *
``