{"version":3,"file":"Color.min.mjs","names":[],"sources":["../../../src/color/Color.ts"],"sourcesContent":["import { normalizeWs } from '../util/internals/normalizeWhiteSpace';\nimport { radiansToDegrees } from '../util/misc/radiansDegreesConversion';\nimport { ColorNameMap } from './color_map';\nimport { reHSLa, reHex, reRGBa } from './constants';\nimport type { TRGBAColorSource, TColorArg } from './typedefs';\nimport {\n  hue2rgb,\n  hexify,\n  rgb2Hsl,\n  fromAlphaToFloat,\n  greyAverage,\n} from './util';\n\n/**\n * @class Color common color operations\n * @see {@link http://fabric5.fabricjs.com/fabric-intro-part-2#colors colors}\n */\nexport class Color {\n  declare private _source: TRGBAColorSource;\n  isUnrecognised = false;\n\n  /**\n   *\n   * @param {string} [color] optional in hex or rgb(a) or hsl format or from known color list\n   */\n  constructor(color?: TColorArg) {\n    if (!color) {\n      // we default to black as canvas does\n      this.setSource([0, 0, 0, 1]);\n    } else if (color instanceof Color) {\n      this.setSource([...color._source]);\n    } else if (Array.isArray(color)) {\n      const [r, g, b, a = 1] = color;\n      this.setSource([r, g, b, a]);\n    } else {\n      this.setSource(this._tryParsingColor(color));\n    }\n  }\n\n  /**\n   * @private\n   * @param {string} [color] Color value to parse\n   * @returns {TRGBAColorSource}\n   */\n  protected _tryParsingColor(color: string) {\n    color = color.toLowerCase();\n    if (color in ColorNameMap) {\n      color = ColorNameMap[color as keyof typeof ColorNameMap];\n    }\n    return color === 'transparent'\n      ? ([255, 255, 255, 0] as TRGBAColorSource)\n      : Color.sourceFromHex(color) ||\n          Color.sourceFromRgb(color) ||\n          Color.sourceFromHsl(color) ||\n          // color is not recognized\n          // we default to black as canvas does\n          // eslint-disable-next-line no-constant-binary-expression\n          ((this.isUnrecognised = true) && ([0, 0, 0, 1] as TRGBAColorSource));\n  }\n\n  /**\n   * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n   * @return {TRGBAColorSource}\n   */\n  getSource() {\n    return this._source;\n  }\n\n  /**\n   * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n   * @param {TRGBAColorSource} source\n   */\n  setSource(source: TRGBAColorSource) {\n    this._source = source;\n  }\n\n  /**\n   * Returns color representation in RGB format\n   * @return {String} ex: rgb(0-255,0-255,0-255)\n   */\n  toRgb() {\n    const [r, g, b] = this.getSource();\n    return `rgb(${r},${g},${b})`;\n  }\n\n  /**\n   * Returns color representation in RGBA format\n   * @return {String} ex: rgba(0-255,0-255,0-255,0-1)\n   */\n  toRgba() {\n    return `rgba(${this.getSource().join(',')})`;\n  }\n\n  /**\n   * Returns color representation in HSL format\n   * @return {String} ex: hsl(0-360,0%-100%,0%-100%)\n   */\n  toHsl() {\n    const [h, s, l] = rgb2Hsl(...this.getSource());\n    return `hsl(${h},${s}%,${l}%)`;\n  }\n\n  /**\n   * Returns color representation in HSLA format\n   * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)\n   */\n  toHsla() {\n    const [h, s, l, a] = rgb2Hsl(...this.getSource());\n    return `hsla(${h},${s}%,${l}%,${a})`;\n  }\n\n  /**\n   * Returns color representation in HEX format\n   * @return {String} ex: FF5555\n   */\n  toHex() {\n    const fullHex = this.toHexa();\n    return fullHex.slice(0, 6);\n  }\n\n  /**\n   * Returns color representation in HEXA format\n   * @return {String} ex: FF5555CC\n   */\n  toHexa() {\n    const [r, g, b, a] = this.getSource();\n    return `${hexify(r)}${hexify(g)}${hexify(b)}${hexify(Math.round(a * 255))}`;\n  }\n\n  /**\n   * Gets value of alpha channel for this color\n   * @return {Number} 0-1\n   */\n  getAlpha() {\n    return this.getSource()[3];\n  }\n\n  /**\n   * Sets value of alpha channel for this color\n   * @param {Number} alpha Alpha value 0-1\n   * @return {Color} thisArg\n   */\n  setAlpha(alpha: number) {\n    this._source[3] = alpha;\n    return this;\n  }\n\n  /**\n   * Transforms color to its grayscale representation\n   * @return {Color} thisArg\n   */\n  toGrayscale() {\n    this.setSource(greyAverage(this.getSource()));\n    return this;\n  }\n\n  /**\n   * Transforms color to its black and white representation\n   * @param {Number} threshold\n   * @return {Color} thisArg\n   */\n  toBlackWhite(threshold: number) {\n    const [average, , , a] = greyAverage(this.getSource()),\n      bOrW = average < (threshold || 127) ? 0 : 255;\n    this.setSource([bOrW, bOrW, bOrW, a]);\n    return this;\n  }\n\n  /**\n   * Overlays color with another color\n   * @param {String|Color} otherColor\n   * @return {Color} thisArg\n   */\n  overlayWith(otherColor: string | Color) {\n    if (!(otherColor instanceof Color)) {\n      otherColor = new Color(otherColor);\n    }\n\n    const source = this.getSource(),\n      otherAlpha = 0.5,\n      otherSource = otherColor.getSource(),\n      [R, G, B] = source.map((value, index) =>\n        Math.round(value * (1 - otherAlpha) + otherSource[index] * otherAlpha),\n      );\n\n    this.setSource([R, G, B, source[3]]);\n    return this;\n  }\n\n  /**\n   * Returns new color object, when given a color in RGB format\n   * @param {String} color Color value ex: rgb(0-255,0-255,0-255)\n   * @return {Color}\n   */\n  static fromRgb(color: string): Color {\n    return Color.fromRgba(color);\n  }\n\n  /**\n   * Returns new color object, when given a color in RGBA format\n   * @param {String} color\n   * @return {Color}\n   */\n  static fromRgba(color: string): Color {\n    return new Color(Color.sourceFromRgb(color));\n  }\n\n  /**\n   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format\n   * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)\n   * @return {TRGBAColorSource | undefined} source\n   */\n  static sourceFromRgb(color: string): TRGBAColorSource | undefined {\n    const match = normalizeWs(color).match(reRGBa());\n    if (match) {\n      const [r, g, b] = match.slice(1, 4).map((value) => {\n        const parsedValue = parseFloat(value);\n        return value.endsWith('%')\n          ? Math.round(parsedValue * 2.55)\n          : parsedValue;\n      });\n      return [r, g, b, fromAlphaToFloat(match[4])];\n    }\n  }\n\n  /**\n   * Returns new color object, when given a color in HSL format\n   * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)\n   * @return {Color}\n   */\n  static fromHsl(color: string): Color {\n    return Color.fromHsla(color);\n  }\n\n  /**\n   * Returns new color object, when given a color in HSLA format\n   * @param {String} color\n   * @return {Color}\n   */\n  static fromHsla(color: string): Color {\n    return new Color(Color.sourceFromHsl(color));\n  }\n\n  /**\n   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.\n   * Adapted from <a href=\"https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html\">https://github.com/mjijackson</a>\n   * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)\n   * @return {TRGBAColorSource | undefined} source\n   * @see http://http://www.w3.org/TR/css3-color/#hsl-color\n   */\n  static sourceFromHsl(color: string): TRGBAColorSource | undefined {\n    const match = normalizeWs(color).match(reHSLa());\n    if (!match) {\n      return;\n    }\n    const match1degrees = Color.parseAngletoDegrees(match[1]);\n\n    const h = (((match1degrees % 360) + 360) % 360) / 360,\n      s = parseFloat(match[2]) / 100,\n      l = parseFloat(match[3]) / 100;\n    let r: number, g: number, b: number;\n\n    if (s === 0) {\n      r = g = b = l;\n    } else {\n      const q = l <= 0.5 ? l * (s + 1) : l + s - l * s,\n        p = l * 2 - q;\n\n      r = hue2rgb(p, q, h + 1 / 3);\n      g = hue2rgb(p, q, h);\n      b = hue2rgb(p, q, h - 1 / 3);\n    }\n\n    return [\n      Math.round(r * 255),\n      Math.round(g * 255),\n      Math.round(b * 255),\n      fromAlphaToFloat(match[4]),\n    ];\n  }\n\n  /**\n   * Returns new color object, when given a color in HEX format\n   * @param {String} color Color value ex: FF5555\n   * @return {Color}\n   */\n  static fromHex(color: string): Color {\n    return new Color(Color.sourceFromHex(color));\n  }\n\n  /**\n   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format\n   * @param {String} color ex: FF5555 or FF5544CC (RGBa)\n   * @return {TRGBAColorSource | undefined} source\n   */\n  static sourceFromHex(color: string): TRGBAColorSource | undefined {\n    if (color.match(reHex())) {\n      const value = color.slice(color.indexOf('#') + 1),\n        isShortNotation = value.length <= 4;\n      let expandedValue: string[];\n      if (isShortNotation) {\n        expandedValue = value.split('').map((hex) => hex + hex);\n      } else {\n        expandedValue = value.match(/.{2}/g)!;\n      }\n      const [r, g, b, a = 255] = expandedValue.map((hexCouple) =>\n        parseInt(hexCouple, 16),\n      );\n      return [r, g, b, a / 255];\n    }\n  }\n\n  /**\n   * Converts a string that could be any angle notation (50deg, 0.5turn, 2rad)\n   * into degrees without the 'deg' suffix\n   * @param {String} value ex: 0deg, 0.5turn, 2rad\n   * @return {Number} number in degrees or NaN if inputs are invalid\n   */\n  static parseAngletoDegrees(value: string): number {\n    const lowercase = value.toLowerCase();\n    const numeric = parseFloat(lowercase);\n\n    if (lowercase.includes('rad')) {\n      return radiansToDegrees(numeric);\n    }\n\n    if (lowercase.includes('turn')) {\n      return numeric * 360;\n    }\n\n    // Value is probably just a number already in degrees eg '50'\n    return numeric;\n  }\n}\n"],"mappings":"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"}