UNPKG

ambilighter

Version:

Ambilight around the video, image or canvas HTML elements

163 lines (91 loc) 3.12 kB
import { IAmbilighter } from '../interfaces/ambilighter.interfaces'; import { IOptions } from '../interfaces/options.interfaces'; import { IOutput } from '../interfaces/output.interface.ts'; import { Ambilighter } from './ambilighter.ts'; import { averageColor, getImageData } from '../utils/adapters'; import { Vector } from '../types/vectors.types.ts'; export class AmbilighterImage extends Ambilighter< HTMLImageElement > implements IAmbilighter { constructor ( el: ( HTMLImageElement | null ), options: IOptions ) { super( el, options ); try { if ( !( el instanceof HTMLImageElement ) ) { throw new Error( 'AmbilighterImage -> constructor :: invalid element' ); } el.onload = (): void => { this.update(); } this.update(); } catch ( e: unknown ) { console.error( e ); } return new Proxy( this, { set( target: AmbilighterImage, prop: ( string | symbol ), handler: (..._args: any) => void ): boolean { if ( prop === 'onUpdate' ) { target[ prop ] = handler; target.update(); } return true; }, } ); } static override validate( el: ( HTMLElement | null ) ): boolean { return el instanceof HTMLImageElement; } protected update (): void { this.updateCanvas( this.el ); const output: IOutput = { frame: { top: { color: averageColor( getImageData( this.canvas, Vector.top ) ), radius: this.radius, }, bottom: { color: averageColor( getImageData( this.canvas, Vector.bottom ) ), radius: this.radius, }, left: { color: averageColor( getImageData( this.canvas, Vector.left ) ), radius: this.radius, }, right: { color: averageColor( getImageData( this.canvas, Vector.right ) ), radius: this.radius, }, }, averageColor: averageColor( getImageData( this.canvas, Vector.bottomRight ) ), }; // Fires onLoad hook this.onUpdate( output ); } /** * Updates when picture repainted * @param image { any } */ protected override updateCanvas ( image: HTMLImageElement ): void { try { const ctx: ( CanvasRenderingContext2D | null ) = this.canvas.getContext( '2d' ); if ( ctx ) { this.canvas.width = image.naturalWidth; this.canvas.height = image.naturalHeight; ctx.drawImage( image, 0, 0, image.naturalWidth, image.naturalHeight ); } } catch ( e: unknown ) { console.error( e ); } } /** * getters / setters */ get radius (): number { return this?.options?.radius || 0; } /** * Hooks */ override onLoad ( ..._args: any ): void { } override onUpdate ( ..._args: any ): void { } override onDestroy(): void { } };