import { ChangeDetectionStrategy, Component, ElementRef, Input, OnChanges, ViewChild, } from '@angular/core'; import { CoordsInterface, DimensionsInterface, } from './../../models/index'; import { ImagePreloaderService, } from './../../helpers/services/index'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'canvas-image-component', styleUrls: [ './canvas-image.component.scss', ], templateUrl: './canvas-image.component.template.pug', }) export class CanvasImageComponent implements OnChanges { @Input() public imageUrl: string; @Input() public colorOverlay: string; @Input() public scale: number = 1; @Input() public globalCompositeOperation = 'source-in'; @ViewChild('canvasElement') public canvasElement: ElementRef; public get canvas(): HTMLCanvasElement { return this.canvasElement.nativeElement; } public get canvasCtx(): CanvasRenderingContext2D { return this.canvas.getContext('2d'); } constructor( private _imagePreloaderService: ImagePreloaderService, ) {} public ngOnChanges() { this.initCanvasSize(); this.loadImages(); } public loadImages() { this._imagePreloaderService.load(this.imageUrl).subscribe((img) => { this.drawOnCanvas( this.canvasCtx, img as HTMLImageElement, this.canvas.offsetWidth, this.canvas.offsetHeight, this.colorOverlay, this.scale, ); }); } public initCanvasSize() { this.canvas.height = this.canvas.offsetHeight; this.canvas.width = this.canvas.offsetWidth; } public drawOnCanvas( canvasContext: CanvasRenderingContext2D, img: HTMLImageElement, fitWidth: number, fitHeight: number, colorOverlay: string, scale: number, ) { const hRatio = fitWidth / img.width; const vRatio = fitHeight / img.height; const ratio = Math.min(hRatio, vRatio); const w = img.width * ratio * scale; const h = img.height * ratio * scale; canvasContext.drawImage( img, fitWidth / 2 - w / 2, fitHeight / 2 - h / 2, w, h, ); this.drawColorOverlay( canvasContext, fitWidth, fitHeight, colorOverlay, ); } public drawColorOverlay( canvasContext: CanvasRenderingContext2D, width: number, height: number, colorOverlay: string, ) { if (colorOverlay) { canvasContext.globalCompositeOperation = this.globalCompositeOperation; canvasContext.fillStyle = colorOverlay; canvasContext.fillRect( 0, 0, width, height, ); } } }