{"version":3,"file":"Polyline.min.mjs","sources":["../../../src/shapes/Polyline.ts"],"sourcesContent":["import { config } from '../config';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport { parsePointsAttribute } from '../parser/parsePointsAttribute';\nimport type { XY } from '../Point';\nimport { Point } from '../Point';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { makeBoundingBoxFromPoints } from '../util/misc/boundingBoxFromPoints';\nimport { calcDimensionsMatrix, transformPoint } from '../util/misc/matrix';\nimport { projectStrokeOnPoints } from '../util/misc/projectStroke';\nimport type { TProjectStrokeOnPointsOptions } from '../util/misc/projectStroke/types';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { toFixed } from '../util/misc/toFixed';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport {\n  CENTER,\n  LEFT,\n  SCALE_X,\n  SCALE_Y,\n  SKEW_X,\n  SKEW_Y,\n  TOP,\n} from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\nimport { escapeXml } from '../util/lang_string';\n\nexport const polylineDefaultValues: Partial<TClassProperties<Polyline>> = {\n  /**\n   * @deprecated transient option soon to be removed in favor of a different design\n   */\n  exactBoundingBox: false,\n};\n\nexport interface SerializedPolylineProps extends SerializedObjectProps {\n  points: XY[];\n}\n\nexport class Polyline<\n  Props extends TOptions<FabricObjectProps> = Partial<FabricObjectProps>,\n  SProps extends SerializedPolylineProps = SerializedPolylineProps,\n  EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject<Props, SProps, EventSpec> {\n  /**\n   * Points array\n   * @type Array\n   */\n  declare points: XY[];\n\n  /**\n   * WARNING: Feature in progress\n   * Calculate the exact bounding box taking in account strokeWidth on acute angles\n   * this will be turned to true by default on fabric 6.0\n   * maybe will be left in as an optimization since calculations may be slow\n   * @deprecated transient option soon to be removed in favor of a different design\n   * @type Boolean\n   * @default false\n   */\n  declare exactBoundingBox: boolean;\n\n  declare private initialized: true | undefined;\n\n  static ownDefaults = polylineDefaultValues;\n\n  static type = 'Polyline';\n\n  static getDefaults(): Record<string, any> {\n    return {\n      ...super.getDefaults(),\n      ...Polyline.ownDefaults,\n    };\n  }\n\n  /**\n   * A list of properties that if changed trigger a recalculation of dimensions\n   * @todo check if you really need to recalculate for all cases\n   */\n  static layoutProperties: (keyof Polyline)[] = [\n    SKEW_X,\n    SKEW_Y,\n    'strokeLineCap',\n    'strokeLineJoin',\n    'strokeMiterLimit',\n    'strokeWidth',\n    'strokeUniform',\n    'points',\n  ];\n\n  declare pathOffset: Point;\n\n  declare strokeOffset: Point;\n\n  static cacheProperties = [...cacheProperties, 'points'];\n\n  strokeDiff: Point;\n\n  /**\n   * Constructor\n   * @param {Array} points Array of points (where each point is an object with x and y)\n   * @param {Object} [options] Options object\n   * @return {Polyline} thisArg\n   * @example\n   * var poly = new Polyline([\n   *     { x: 10, y: 10 },\n   *     { x: 50, y: 30 },\n   *     { x: 40, y: 70 },\n   *     { x: 60, y: 50 },\n   *     { x: 100, y: 150 },\n   *     { x: 40, y: 100 }\n   *   ], {\n   *   stroke: 'red',\n   *   left: 100,\n   *   top: 100\n   * });\n   */\n  constructor(points: XY[] = [], options: Props = {} as Props) {\n    super();\n    Object.assign(this, Polyline.ownDefaults);\n    this.setOptions(options);\n    this.points = points;\n    const { left, top } = options;\n    this.initialized = true;\n    this.setBoundingBox(true);\n    typeof left === 'number' && this.set(LEFT, left);\n    typeof top === 'number' && this.set(TOP, top);\n  }\n\n  protected isOpen() {\n    return true;\n  }\n\n  private _projectStrokeOnPoints(options: TProjectStrokeOnPointsOptions) {\n    return projectStrokeOnPoints(this.points, options, this.isOpen());\n  }\n\n  /**\n   * Calculate the polygon bounding box\n   * @private\n   */\n  _calcDimensions(options?: Partial<TProjectStrokeOnPointsOptions>) {\n    options = {\n      scaleX: this.scaleX,\n      scaleY: this.scaleY,\n      skewX: this.skewX,\n      skewY: this.skewY,\n      strokeLineCap: this.strokeLineCap,\n      strokeLineJoin: this.strokeLineJoin,\n      strokeMiterLimit: this.strokeMiterLimit,\n      strokeUniform: this.strokeUniform,\n      strokeWidth: this.strokeWidth,\n      ...(options || {}),\n    };\n    const points = this.exactBoundingBox\n      ? this._projectStrokeOnPoints(\n          options as TProjectStrokeOnPointsOptions,\n        ).map((projection) => projection.projectedPoint)\n      : this.points;\n    if (points.length === 0) {\n      return {\n        left: 0,\n        top: 0,\n        width: 0,\n        height: 0,\n        pathOffset: new Point(),\n        strokeOffset: new Point(),\n        strokeDiff: new Point(),\n      };\n    }\n    const bbox = makeBoundingBoxFromPoints(points),\n      // Remove scale effect, since it's applied after\n      matrix = calcDimensionsMatrix({ ...options, scaleX: 1, scaleY: 1 }),\n      bboxNoStroke = makeBoundingBoxFromPoints(\n        this.points.map((p) => transformPoint(p, matrix, true)),\n      ),\n      scale = new Point(this.scaleX, this.scaleY);\n    let offsetX = bbox.left + bbox.width / 2,\n      offsetY = bbox.top + bbox.height / 2;\n    if (this.exactBoundingBox) {\n      offsetX = offsetX - offsetY * Math.tan(degreesToRadians(this.skewX));\n      // Order of those assignments is important.\n      // offsetY relies on offsetX being already changed by the line above\n      offsetY = offsetY - offsetX * Math.tan(degreesToRadians(this.skewY));\n    }\n\n    return {\n      ...bbox,\n      pathOffset: new Point(offsetX, offsetY),\n      strokeOffset: new Point(bboxNoStroke.left, bboxNoStroke.top)\n        .subtract(new Point(bbox.left, bbox.top))\n        .multiply(scale),\n      strokeDiff: new Point(bbox.width, bbox.height)\n        .subtract(new Point(bboxNoStroke.width, bboxNoStroke.height))\n        .multiply(scale),\n    };\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, by look at the polyline/polygon points.\n   * @private\n   * @return {Point} center point from element coordinates\n   */\n  _findCenterFromElement(): Point {\n    const bbox = makeBoundingBoxFromPoints(this.points);\n    return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);\n  }\n\n  setDimensions() {\n    this.setBoundingBox();\n  }\n\n  setBoundingBox(adjustPosition?: boolean) {\n    const { left, top, width, height, pathOffset, strokeOffset, strokeDiff } =\n      this._calcDimensions();\n    this.set({ width, height, pathOffset, strokeOffset, strokeDiff });\n    adjustPosition &&\n      this.setPositionByOrigin(\n        new Point(left + width / 2, top + height / 2),\n        CENTER,\n        CENTER,\n      );\n  }\n\n  /**\n   * @deprecated intermidiate method to be removed, do not use\n   */\n  protected isStrokeAccountedForInDimensions() {\n    return this.exactBoundingBox;\n  }\n\n  /**\n   * @override stroke is taken in account in size\n   */\n  _getNonTransformedDimensions() {\n    return this.exactBoundingBox\n      ? // TODO: fix this\n        new Point(this.width, this.height)\n      : super._getNonTransformedDimensions();\n  }\n\n  /**\n   * @override stroke and skewing are taken into account when projecting stroke on points,\n   * therefore we don't want the default calculation to account for skewing as well.\n   * Though it is possible to pass `width` and `height` in `options`, doing so is very strange, use with discretion.\n   *\n   * @private\n   */\n  _getTransformedDimensions(options: any = {}) {\n    if (this.exactBoundingBox) {\n      let size: Point;\n      /* When `strokeUniform = true`, any changes to the properties require recalculating the `width` and `height` because\n        the stroke projections are affected.\n        When `strokeUniform = false`, we don't need to recalculate for scale transformations, as the effect of scale on\n        projections follows a linear function (e.g. scaleX of 2 just multiply width by 2)*/\n      if (\n        Object.keys(options).some(\n          (key) =>\n            this.strokeUniform ||\n            (this.constructor as typeof Polyline).layoutProperties.includes(\n              key as keyof TProjectStrokeOnPointsOptions,\n            ),\n        )\n      ) {\n        const { width, height } = this._calcDimensions(options);\n        size = new Point(options.width ?? width, options.height ?? height);\n      } else {\n        size = new Point(\n          options.width ?? this.width,\n          options.height ?? this.height,\n        );\n      }\n      return size.multiply(\n        new Point(options.scaleX || this.scaleX, options.scaleY || this.scaleY),\n      );\n    } else {\n      return super._getTransformedDimensions(options);\n    }\n  }\n\n  /**\n   * Recalculates dimensions when changing skew and scale\n   * @private\n   */\n  _set(key: string, value: any) {\n    const changed = this.initialized && this[key as keyof this] !== value;\n    const output = super._set(key, value);\n    if (\n      this.exactBoundingBox &&\n      changed &&\n      (((key === SCALE_X || key === SCALE_Y) &&\n        this.strokeUniform &&\n        (this.constructor as typeof Polyline).layoutProperties.includes(\n          'strokeUniform',\n        )) ||\n        (this.constructor as typeof Polyline).layoutProperties.includes(\n          key as keyof Polyline,\n        ))\n    ) {\n      this.setDimensions();\n    }\n    return output;\n  }\n\n  /**\n   * Returns object representation of an instance\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      points: this.points.map(({ x, y }) => ({ x, y })),\n    };\n  }\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 diffX = this.pathOffset.x,\n      diffY = this.pathOffset.y,\n      NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS;\n\n    const points = this.points\n      .map(\n        ({ x, y }) =>\n          `${toFixed(x - diffX, NUM_FRACTION_DIGITS)},${toFixed(y - diffY, NUM_FRACTION_DIGITS)}`,\n      )\n      .join(' ');\n\n    return [\n      `<${\n        escapeXml((this.constructor as typeof Polyline).type).toLowerCase() as\n          | 'polyline'\n          | 'polygon'\n      } `,\n      'COMMON_PARTS',\n      `points=\"${points}\" />\\n`,\n    ];\n  }\n\n  /**\n   * @private\n   * @param {CanvasRenderingContext2D} ctx Context to render on\n   */\n  _render(ctx: CanvasRenderingContext2D) {\n    const len = this.points.length,\n      x = this.pathOffset.x,\n      y = this.pathOffset.y;\n\n    if (!len || isNaN(this.points[len - 1].y)) {\n      // do not draw if no points or odd points\n      // NaN comes from parseFloat of a empty string in parser\n      return;\n    }\n    ctx.beginPath();\n    ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n    for (let i = 0; i < len; i++) {\n      const point = this.points[i];\n      ctx.lineTo(point.x - x, point.y - y);\n    }\n    !this.isOpen() && ctx.closePath();\n    this._renderPaintInOrder(ctx);\n  }\n\n  /**\n   * Returns complexity of an instance\n   * @return {Number} complexity of this instance\n   */\n  complexity(): number {\n    return this.points.length;\n  }\n\n  /* _FROM_SVG_START_ */\n\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link Polyline.fromElement})\n   * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n   */\n  static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES];\n\n  /**\n   * Returns Polyline instance from an SVG element\n   * @param {HTMLElement} element Element to parser\n   * @param {Object} [options] Options object\n   */\n  static async fromElement(\n    element: HTMLElement | SVGElement,\n    options?: Abortable,\n    cssRules?: CSSRules,\n  ) {\n    const points = parsePointsAttribute(element.getAttribute('points')),\n      // we omit left and top to instruct the constructor to position the object using the bbox\n\n      { left, top, ...parsedAttributes } = parseAttributes(\n        element,\n        this.ATTRIBUTE_NAMES,\n        cssRules,\n      );\n    return new this(points, {\n      ...parsedAttributes,\n      ...options,\n    });\n  }\n\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns Polyline instance from an object representation\n   * @param {Object} object Object to create an instance from\n   * @returns {Promise<Polyline>}\n   */\n  static fromObject<T extends TOptions<SerializedPolylineProps>>(object: T) {\n    return this._fromObject<Polyline>(object, {\n      extraParam: 'points',\n    });\n  }\n}\n\nclassRegistry.setClass(Polyline);\nclassRegistry.setSVGClass(Polyline);\n"],"names":["polylineDefaultValues","exactBoundingBox","Polyline","FabricObject","getDefaults","super","ownDefaults","constructor","points","arguments","length","undefined","options","_defineProperty","this","Object","assign","setOptions","left","top","initialized","setBoundingBox","set","LEFT","TOP","isOpen","_projectStrokeOnPoints","projectStrokeOnPoints","_calcDimensions","scaleX","scaleY","skewX","skewY","strokeLineCap","strokeLineJoin","strokeMiterLimit","strokeUniform","strokeWidth","map","projection","projectedPoint","width","height","pathOffset","Point","strokeOffset","strokeDiff","bbox","makeBoundingBoxFromPoints","matrix","calcDimensionsMatrix","bboxNoStroke","p","transformPoint","scale","offsetX","offsetY","Math","tan","degreesToRadians","subtract","multiply","_findCenterFromElement","setDimensions","adjustPosition","setPositionByOrigin","CENTER","isStrokeAccountedForInDimensions","_getNonTransformedDimensions","_getTransformedDimensions","size","keys","some","key","layoutProperties","includes","_options$width","_options$height","_options$width2","_options$height2","_set","value","changed","output","SCALE_X","SCALE_Y","toObject","propertiesToInclude","_ref","x","y","_toSVG","diffX","diffY","NUM_FRACTION_DIGITS","config","_ref2","toFixed","join","escapeXml","type","toLowerCase","_render","ctx","len","isNaN","beginPath","moveTo","i","point","lineTo","closePath","_renderPaintInOrder","complexity","fromElement","element","cssRules","parsePointsAttribute","getAttribute","parsedAttributes","parseAttributes","ATTRIBUTE_NAMES","fromObject","object","_fromObject","extraParam","SKEW_X","SKEW_Y","cacheProperties","SHARED_ATTRIBUTES","classRegistry","setClass","setSVGClass"],"mappings":"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"}