UNPKG

fabric

Version:

Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.

66 lines (63 loc) 2.38 kB
/** * Canvas 2D filter backend. */ import type { BaseFilter } from './BaseFilter'; import type { T2DPipelineState, TPipelineResources } from './typedefs'; export class Canvas2dFilterBackend { /** * Experimental. This object is a sort of repository of help layers used to avoid * of recreating them during frequent filtering. If you are previewing a filter with * a slider you probably do not want to create help layers every filter step. * in this object there will be appended some canvases, created once, resized sometimes * cleared never. Clearing is left to the developer. **/ resources: TPipelineResources = {}; /** * Apply a set of filters against a source image and draw the filtered output * to the provided destination canvas. * * @param {EnhancedFilter} filters The filter to apply. * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered. * @param {Number} sourceWidth The width of the source input. * @param {Number} sourceHeight The height of the source input. * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn. */ applyFilters( filters: BaseFilter<string, Record<string, any>>[], sourceElement: CanvasImageSource, sourceWidth: number, sourceHeight: number, targetCanvas: HTMLCanvasElement, ): T2DPipelineState | void { const ctx = targetCanvas.getContext('2d'); if (!ctx) { return; } ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight); const imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); const originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); const pipelineState: T2DPipelineState = { sourceWidth, sourceHeight, imageData, originalEl: sourceElement, originalImageData, canvasEl: targetCanvas, ctx, filterBackend: this, }; filters.forEach((filter) => { filter.applyTo(pipelineState); }); const { imageData: imageDataPostFilter } = pipelineState; if ( imageDataPostFilter.width !== sourceWidth || imageDataPostFilter.height !== sourceHeight ) { targetCanvas.width = imageDataPostFilter.width; targetCanvas.height = imageDataPostFilter.height; } ctx.putImageData(imageDataPostFilter, 0, 0); return pipelineState; } }