UNPKG

ambilighter

Version:

Ambilight around the video, image or canvas HTML elements

153 lines (87 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 AmbilighterVideo extends Ambilighter< HTMLVideoElement > implements IAmbilighter { constructor ( el: ( HTMLVideoElement | null ), options: IOptions ) { super( el, options ); try { if ( !( el instanceof HTMLVideoElement ) ) { throw new Error( 'AmbilighterVideo -> constructor :: invalid element' ); } this.init(); } catch ( e: unknown ) { console.error( e ); } } static override validate( el: ( HTMLElement | null ) ): boolean { return el instanceof HTMLVideoElement; } protected init(): void { this.el.addEventListener( 'loadedmetadata', (): void => this.update() ); this.el.addEventListener( 'timeupdate', (): void => this.update() ); } protected deinit(): void { this.el.removeEventListener( 'loadedmetadata', (): void => this.update() ); this.el.removeEventListener( 'timeupdate', (): void => this.update() ); } 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 video { any } */ protected override updateCanvas ( video: HTMLVideoElement ): void { try { const ctx: ( CanvasRenderingContext2D | null ) = this.canvas.getContext( '2d' ); if ( ctx ) { this.canvas.width = video.videoWidth; this.canvas.height = video.videoHeight; ctx.drawImage( video, 0, 0, video.videoWidth, video.videoHeight ); } } 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 { } };