{"version":3,"file":"BlendImage.mjs","sources":["../../../src/filters/BlendImage.ts"],"sourcesContent":["import { FabricImage } from '../shapes/Image';\nimport type { TClassProperties } from '../typedefs';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { BaseFilter } from './BaseFilter';\nimport type {\n  T2DPipelineState,\n  TWebGLPipelineState,\n  TWebGLUniformLocationMap,\n} from './typedefs';\nimport type { WebGLFilterBackend } from './WebGLFilterBackend';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/blendImage';\n\nexport type TBlendImageMode = 'multiply' | 'mask';\n\nexport const blendImageDefaultValues: Partial<TClassProperties<BlendImage>> = {\n  mode: 'multiply',\n  alpha: 1,\n  vertexSource: `\n    attribute vec2 aPosition;\n    varying vec2 vTexCoord;\n    varying vec2 vTexCoord2;\n    uniform mat3 uTransformMatrix;\n    void main() {\n      vTexCoord = aPosition;\n      vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n      gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n    }\n    `,\n};\n\n/**\n * Image Blend filter class\n * @example\n * const filter = new filters.BlendColor({\n *  color: '#000',\n *  mode: 'multiply'\n * });\n *\n * const filter = new BlendImage({\n *  image: fabricImageObject,\n *  mode: 'multiply'\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class BlendImage extends BaseFilter {\n  /**\n   * Image to make the blend operation with.\n   **/\n  declare image: FabricImage;\n\n  /**\n   * Blend mode for the filter: either 'multiply' or 'mask'. 'multiply' will\n   * multiply the values of each channel (R, G, B, and A) of the filter image by\n   * their corresponding values in the base image. 'mask' will only look at the\n   * alpha channel of the filter image, and apply those values to the base\n   * image's alpha channel.\n   * @type String\n   * @default\n   **/\n  declare mode: TBlendImageMode;\n\n  /**\n   * alpha value. represent the strength of the blend image operation.\n   * not implemented.\n   **/\n  declare alpha: number;\n\n  static type = 'BlendImage';\n\n  static defaults = blendImageDefaultValues;\n\n  getCacheKey() {\n    return `${this.type}_${this.mode}`;\n  }\n\n  getFragmentSource(): string {\n    return fragmentSource[this.mode];\n  }\n\n  applyToWebGL(options: TWebGLPipelineState) {\n    const gl = options.context,\n      texture = this.createTexture(options.filterBackend, this.image);\n    this.bindAdditionalTexture(gl, texture!, gl.TEXTURE1);\n    super.applyToWebGL(options);\n    this.unbindAdditionalTexture(gl, gl.TEXTURE1);\n  }\n\n  createTexture(backend: WebGLFilterBackend, image: FabricImage) {\n    return backend.getCachedTexture(image.cacheKey, image.getElement());\n  }\n\n  /**\n   * Calculate a transformMatrix to adapt the image to blend over\n   * @param {Object} options\n   * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n   * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n   */\n  calculateMatrix() {\n    const image = this.image,\n      { width, height } = image.getElement();\n    return [\n      1 / image.scaleX,\n      0,\n      0,\n      0,\n      1 / image.scaleY,\n      0,\n      -image.left / width,\n      -image.top / height,\n      1,\n    ];\n  }\n\n  /**\n   * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n   *\n   * @param {Object} options\n   * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n   */\n  applyTo2d({\n    imageData: { data, width, height },\n    filterBackend: { resources },\n  }: T2DPipelineState) {\n    const image = this.image;\n    if (!resources.blendImage) {\n      resources.blendImage = createCanvasElement();\n    }\n    const canvas1 = resources.blendImage;\n    const context = canvas1.getContext('2d')!;\n    if (canvas1.width !== width || canvas1.height !== height) {\n      canvas1.width = width;\n      canvas1.height = height;\n    } else {\n      context.clearRect(0, 0, width, height);\n    }\n    context.setTransform(\n      image.scaleX,\n      0,\n      0,\n      image.scaleY,\n      image.left,\n      image.top\n    );\n    context.drawImage(image.getElement(), 0, 0, width, height);\n    const blendData = context.getImageData(0, 0, width, height).data;\n    for (let i = 0; i < data.length; i += 4) {\n      const r = data[i];\n      const g = data[i + 1];\n      const b = data[i + 2];\n      const a = data[i + 3];\n\n      const tr = blendData[i];\n      const tg = blendData[i + 1];\n      const tb = blendData[i + 2];\n      const ta = blendData[i + 3];\n\n      switch (this.mode) {\n        case 'multiply':\n          data[i] = (r * tr) / 255;\n          data[i + 1] = (g * tg) / 255;\n          data[i + 2] = (b * tb) / 255;\n          data[i + 3] = (a * ta) / 255;\n          break;\n        case 'mask':\n          data[i + 3] = ta;\n          break;\n      }\n    }\n  }\n\n  /**\n   * Return WebGL uniform locations for this filter's shader.\n   *\n   * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n   * @param {WebGLShaderProgram} program This filter's compiled shader program.\n   */\n  getUniformLocations(\n    gl: WebGLRenderingContext,\n    program: WebGLProgram\n  ): TWebGLUniformLocationMap {\n    return {\n      uTransformMatrix: gl.getUniformLocation(program, 'uTransformMatrix'),\n      uImage: gl.getUniformLocation(program, 'uImage'),\n    };\n  }\n\n  /**\n   * Send data from this filter to its shader program's uniforms.\n   *\n   * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n   * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n   */\n  sendUniformData(\n    gl: WebGLRenderingContext,\n    uniformLocations: TWebGLUniformLocationMap\n  ) {\n    const matrix = this.calculateMatrix();\n    gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.\n    gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);\n  }\n\n  /**\n   * Returns object representation of an instance\n   * @return {Object} Object representation of an instance\n   */\n  toObject() {\n    return {\n      type: this.type,\n      image: this.image && this.image.toObject(),\n      mode: this.mode,\n      alpha: this.alpha,\n    };\n  }\n\n  /**\n   * Create filter instance from an object representation\n   * @static\n   * @param {object} object Object to create an instance from\n   * @param {object} [options]\n   * @param {AbortSignal} [options.signal] handle aborting image loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n   * @returns {Promise<BlendImage>}\n   */\n  static fromObject(\n    { type, image, ...filterOptions }: Record<string, any>,\n    options: { signal: AbortSignal }\n  ) {\n    return FabricImage.fromObject(image, options).then(\n      (enlivedImage) =>\n        new this({ ...filterOptions, image: enlivedImage }) as BaseFilter\n    );\n  }\n}\n\nclassRegistry.setClass(BlendImage);\n"],"names":["blendImageDefaultValues","mode","alpha","vertexSource","BlendImage","BaseFilter","getCacheKey","concat","type","getFragmentSource","fragmentSource","applyToWebGL","options","gl","context","texture","createTexture","filterBackend","image","bindAdditionalTexture","TEXTURE1","unbindAdditionalTexture","backend","getCachedTexture","cacheKey","getElement","calculateMatrix","width","height","scaleX","scaleY","left","top","applyTo2d","_ref","imageData","data","resources","blendImage","createCanvasElement","canvas1","getContext","clearRect","setTransform","drawImage","blendData","getImageData","i","length","r","g","b","a","tr","tg","tb","ta","getUniformLocations","program","uTransformMatrix","getUniformLocation","uImage","sendUniformData","uniformLocations","matrix","uniform1i","uniformMatrix3fv","toObject","fromObject","_ref2","filterOptions","_objectWithoutProperties","_excluded","FabricImage","then","enlivedImage","_objectSpread","_defineProperty","classRegistry","setClass"],"mappings":"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"}