{"version":3,"file":"Line.min.mjs","sources":["../../../src/shapes/Line.ts"],"sourcesContent":["import { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport { Point } from '../Point';\nimport { isFiller } from '../util/typeAssertions';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport { makeBoundingBoxFromPoints } from '../util';\nimport { CENTER, LEFT, TOP } from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\n// @TODO this code is terrible and Line should be a special case of polyline.\n\nconst coordProps = ['x1', 'x2', 'y1', 'y2'] as const;\n\ninterface UniqueLineProps {\n  x1: number;\n  x2: number;\n  y1: number;\n  y2: number;\n}\n\nexport interface SerializedLineProps\n  extends SerializedObjectProps,\n    UniqueLineProps {}\n\nexport class Line<\n    Props extends TOptions<FabricObjectProps> = Partial<FabricObjectProps>,\n    SProps extends SerializedLineProps = SerializedLineProps,\n    EventSpec extends ObjectEvents = ObjectEvents\n  >\n  extends FabricObject<Props, SProps, EventSpec>\n  implements UniqueLineProps\n{\n  /**\n   * x value or first line edge\n   * @type number\n   * @default\n   */\n  declare x1: number;\n\n  /**\n   * y value or first line edge\n   * @type number\n   * @default\n   */\n  declare y1: number;\n\n  /**\n   * x value or second line edge\n   * @type number\n   * @default\n   */\n  declare x2: number;\n\n  /**\n   * y value or second line edge\n   * @type number\n   * @default\n   */\n  declare y2: number;\n\n  static type = 'Line';\n\n  static cacheProperties = [...cacheProperties, ...coordProps];\n  /**\n   * Constructor\n   * @param {Array} [points] Array of points\n   * @param {Object} [options] Options object\n   * @return {Line} thisArg\n   */\n  constructor([x1, y1, x2, y2] = [0, 0, 0, 0], options: Props = {} as Props) {\n    super({ ...options, x1, y1, x2, y2 });\n    this._setWidthHeight();\n    const { left, top } = options;\n    typeof left === 'number' && this.set(LEFT, left);\n    typeof top === 'number' && this.set(TOP, top);\n  }\n\n  /**\n   * @private\n   * @param {Object} [options] Options\n   */\n  _setWidthHeight() {\n    const { x1, y1, x2, y2 } = this;\n    this.width = Math.abs(x2 - x1);\n    this.height = Math.abs(y2 - y1);\n    const { left, top, width, height } = makeBoundingBoxFromPoints([\n      { x: x1, y: y1 },\n      { x: x2, y: y2 },\n    ]);\n    const position = new Point(left + width / 2, top + height / 2);\n    this.setPositionByOrigin(position, CENTER, CENTER);\n  }\n\n  /**\n   * @private\n   * @param {String} key\n   * @param {*} value\n   */\n  _set(key: string, value: any) {\n    super._set(key, value);\n    if (coordProps.includes(key as keyof UniqueLineProps)) {\n      // this doesn't make sense very much, since setting x1 when top or left\n      // are already set, is just going to show a strange result since the\n      // line will move way more than the developer expect.\n      // in fabric5 it worked only when the line didn't have extra transformations,\n      // in fabric6 too. With extra transform they behave bad in different ways.\n      // This needs probably a good rework or a tutorial if you have to create a dynamic line\n      this._setWidthHeight();\n    }\n    return this;\n  }\n\n  /**\n   * @private\n   * @param {CanvasRenderingContext2D} ctx Context to render on\n   */\n  _render(ctx: CanvasRenderingContext2D) {\n    ctx.beginPath();\n\n    const p = this.calcLinePoints();\n    ctx.moveTo(p.x1, p.y1);\n    ctx.lineTo(p.x2, p.y2);\n\n    ctx.lineWidth = this.strokeWidth;\n\n    // TODO: test this\n    // make sure setting \"fill\" changes color of a line\n    // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n    const origStrokeStyle = ctx.strokeStyle;\n    if (isFiller(this.stroke)) {\n      ctx.strokeStyle = this.stroke.toLive(ctx)!;\n    } else {\n      ctx.strokeStyle = this.stroke ?? ctx.fillStyle;\n    }\n    this.stroke && this._renderStroke(ctx);\n    ctx.strokeStyle = origStrokeStyle;\n  }\n\n  /**\n   * This function is an helper for svg import. it returns the center of the object in the svg\n   * untransformed coordinates\n   * @private\n   * @return {Point} center point from element coordinates\n   */\n  _findCenterFromElement(): Point {\n    return new Point((this.x1 + this.x2) / 2, (this.y1 + this.y2) / 2);\n  }\n\n  /**\n   * Returns object representation of an instance\n   * @method toObject\n   * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n   * @return {Object} object representation of an instance\n   */\n  toObject<\n    T extends Omit<Props & TClassProperties<this>, keyof SProps>,\n    K extends keyof T = never\n  >(propertiesToInclude: K[] = []): Pick<T, K> & SProps {\n    return {\n      ...super.toObject(propertiesToInclude),\n      ...this.calcLinePoints(),\n    };\n  }\n\n  /*\n   * Calculate object dimensions from its properties\n   * @private\n   */\n  _getNonTransformedDimensions(): Point {\n    const dim = super._getNonTransformedDimensions();\n    if (this.strokeLineCap === 'butt') {\n      if (this.width === 0) {\n        dim.y -= this.strokeWidth;\n      }\n      if (this.height === 0) {\n        dim.x -= this.strokeWidth;\n      }\n    }\n    return dim;\n  }\n\n  /**\n   * Recalculates line points given width and height\n   * Those points are simply placed around the center,\n   * This is not useful outside internal render functions and svg output\n   * Is not meant to be for the developer.\n   * @private\n   */\n  calcLinePoints(): UniqueLineProps {\n    const { x1: _x1, x2: _x2, y1: _y1, y2: _y2, width, height } = this;\n    const xMult = _x1 <= _x2 ? -1 : 1,\n      yMult = _y1 <= _y2 ? -1 : 1,\n      x1 = (xMult * width) / 2,\n      y1 = (yMult * height) / 2,\n      x2 = (xMult * -width) / 2,\n      y2 = (yMult * -height) / 2;\n\n    return {\n      x1,\n      x2,\n      y1,\n      y2,\n    };\n  }\n\n  /* _FROM_SVG_START_ */\n\n  /**\n   * Returns svg representation of an instance\n   * @return {Array} an array of strings with the specific svg representation\n   * of the instance\n   */\n  _toSVG() {\n    const { x1, x2, y1, y2 } = this.calcLinePoints();\n    return [\n      '<line ',\n      'COMMON_PARTS',\n      `x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" />\\n`,\n    ];\n  }\n\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link Line.fromElement})\n   * @static\n   * @memberOf Line\n   * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n   */\n  static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat(coordProps);\n\n  /**\n   * Returns Line instance from an SVG element\n   * @static\n   * @memberOf Line\n   * @param {HTMLElement} element Element to parse\n   * @param {Object} [options] Options object\n   * @param {Function} [callback] callback function invoked after parsing\n   */\n  static async fromElement(\n    element: HTMLElement,\n    options: Abortable,\n    cssRules?: CSSRules\n  ) {\n    const {\n      x1 = 0,\n      y1 = 0,\n      x2 = 0,\n      y2 = 0,\n      ...parsedAttributes\n    } = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);\n    return new this([x1, y1, x2, y2], parsedAttributes);\n  }\n\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns Line instance from an object representation\n   * @static\n   * @memberOf Line\n   * @param {Object} object Object to create an instance from\n   * @returns {Promise<Line>}\n   */\n  static fromObject<T extends TOptions<SerializedLineProps>>({\n    x1,\n    y1,\n    x2,\n    y2,\n    ...object\n  }: T) {\n    return this._fromObject<Line>(\n      {\n        ...object,\n        points: [x1, y1, x2, y2],\n      },\n      {\n        extraParam: 'points',\n      }\n    );\n  }\n}\n\nclassRegistry.setClass(Line);\nclassRegistry.setSVGClass(Line);\n"],"names":["coordProps","Line","FabricObject","constructor","x1","y1","x2","y2","arguments","length","undefined","options","super","_objectSpread","this","_setWidthHeight","left","top","set","LEFT","TOP","width","Math","abs","height","makeBoundingBoxFromPoints","x","y","position","Point","setPositionByOrigin","CENTER","_set","key","value","includes","_render","ctx","beginPath","p","calcLinePoints","moveTo","lineTo","lineWidth","strokeWidth","origStrokeStyle","strokeStyle","_this$stroke","isFiller","stroke","toLive","fillStyle","_renderStroke","_findCenterFromElement","toObject","propertiesToInclude","_getNonTransformedDimensions","dim","strokeLineCap","_x1","_x2","_y1","_y2","xMult","yMult","_toSVG","concat","fromElement","element","cssRules","_parseAttributes","parseAttributes","ATTRIBUTE_NAMES","_objectWithoutProperties","_excluded","fromObject","_ref","object","_excluded2","_fromObject","points","extraParam","_defineProperty","cacheProperties","SHARED_ATTRIBUTES","classRegistry","setClass","setSVGClass"],"mappings":"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"}