9033627b4c16d5ba2e42393803604ffc.json 50.1 KB
{"ast":null,"code":"/**\r\n * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>\r\n * @fileoverview Shape component\r\n */\nimport fabric from 'fabric';\nimport Component from '../interface/component';\nimport { rejectMessages, eventNames, keyCodes as KEY_CODES, componentNames, fObjectOptions, SHAPE_DEFAULT_OPTIONS, SHAPE_FILL_TYPE } from '../consts';\nimport resizeHelper from '../helper/shapeResizeHelper';\nimport { getFillImageFromShape, rePositionFilterTypeFillImage, reMakePatternImageSource, makeFillPatternForFilter, makeFilterOptionFromFabricImage, resetFillPatternCanvas } from '../helper/shapeFilterFillHelper';\nimport { Promise, changeOrigin, getCustomProperty, getFillTypeFromOption, getFillTypeFromObject, isShape } from '../util';\nimport { extend } from 'tui-code-snippet';\nconst SHAPE_INIT_OPTIONS = extend({\n  strokeWidth: 1,\n  stroke: '#000000',\n  fill: '#ffffff',\n  width: 1,\n  height: 1,\n  rx: 0,\n  ry: 0\n}, SHAPE_DEFAULT_OPTIONS);\nconst DEFAULT_TYPE = 'rect';\nconst DEFAULT_WIDTH = 20;\nconst DEFAULT_HEIGHT = 20;\n/**\r\n * Make fill option\r\n * @param {Object} options - Options to create the shape\r\n * @param {Object.Image} canvasImage - canvas background image\r\n * @param {Function} createStaticCanvas - static canvas creater\r\n * @returns {Object} - shape option\r\n * @private\r\n */\n\nfunction makeFabricFillOption(options, canvasImage, createStaticCanvas) {\n  const fillOption = options.fill;\n  const fillType = getFillTypeFromOption(options.fill);\n  let fill = fillOption;\n\n  if (fillOption.color) {\n    fill = fillOption.color;\n  }\n\n  let extOption = null;\n\n  if (fillType === 'filter') {\n    const newStaticCanvas = createStaticCanvas();\n    extOption = makeFillPatternForFilter(canvasImage, fillOption.filter, newStaticCanvas);\n  } else {\n    extOption = {\n      fill\n    };\n  }\n\n  return extend({}, options, extOption);\n}\n/**\r\n * Shape\r\n * @class Shape\r\n * @param {Graphics} graphics - Graphics instance\r\n * @extends {Component}\r\n * @ignore\r\n */\n\n\nexport default class Shape extends Component {\n  constructor(graphics) {\n    super(componentNames.SHAPE, graphics);\n    /**\r\n     * Object of The drawing shape\r\n     * @type {fabric.Object}\r\n     * @private\r\n     */\n\n    this._shapeObj = null;\n    /**\r\n     * Type of the drawing shape\r\n     * @type {string}\r\n     * @private\r\n     */\n\n    this._type = DEFAULT_TYPE;\n    /**\r\n     * Options to draw the shape\r\n     * @type {Object}\r\n     * @private\r\n     */\n\n    this._options = extend({}, SHAPE_INIT_OPTIONS);\n    /**\r\n     * Whether the shape object is selected or not\r\n     * @type {boolean}\r\n     * @private\r\n     */\n\n    this._isSelected = false;\n    /**\r\n     * Pointer for drawing shape (x, y)\r\n     * @type {Object}\r\n     * @private\r\n     */\n\n    this._startPoint = {};\n    /**\r\n     * Using shortcut on drawing shape\r\n     * @type {boolean}\r\n     * @private\r\n     */\n\n    this._withShiftKey = false;\n    /**\r\n     * Event handler list\r\n     * @type {Object}\r\n     * @private\r\n     */\n\n    this._handlers = {\n      mousedown: this._onFabricMouseDown.bind(this),\n      mousemove: this._onFabricMouseMove.bind(this),\n      mouseup: this._onFabricMouseUp.bind(this),\n      keydown: this._onKeyDown.bind(this),\n      keyup: this._onKeyUp.bind(this)\n    };\n  }\n  /**\r\n   * Start to draw the shape on canvas\r\n   * @ignore\r\n   */\n\n\n  start() {\n    const canvas = this.getCanvas();\n    this._isSelected = false;\n    canvas.defaultCursor = 'crosshair';\n    canvas.selection = false;\n    canvas.uniformScaling = true;\n    canvas.on({\n      'mouse:down': this._handlers.mousedown\n    });\n    fabric.util.addListener(document, 'keydown', this._handlers.keydown);\n    fabric.util.addListener(document, 'keyup', this._handlers.keyup);\n  }\n  /**\r\n   * End to draw the shape on canvas\r\n   * @ignore\r\n   */\n\n\n  end() {\n    const canvas = this.getCanvas();\n    this._isSelected = false;\n    canvas.defaultCursor = 'default';\n    canvas.selection = true;\n    canvas.uniformScaling = false;\n    canvas.off({\n      'mouse:down': this._handlers.mousedown\n    });\n    fabric.util.removeListener(document, 'keydown', this._handlers.keydown);\n    fabric.util.removeListener(document, 'keyup', this._handlers.keyup);\n  }\n  /**\r\n   * Set states of the current drawing shape\r\n   * @ignore\r\n   * @param {string} type - Shape type (ex: 'rect', 'circle')\r\n   * @param {Object} [options] - Shape options\r\n   *      @param {(ShapeFillOption | string)} [options.fill] - {@link ShapeFillOption} or\r\n   *        Shape foreground color (ex: '#fff', 'transparent')\r\n   *      @param {string} [options.stoke] - Shape outline color\r\n   *      @param {number} [options.strokeWidth] - Shape outline width\r\n   *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)\r\n   */\n\n\n  setStates(type, options) {\n    this._type = type;\n\n    if (options) {\n      this._options = extend(this._options, options);\n    }\n  }\n  /**\r\n   * Add the shape\r\n   * @ignore\r\n   * @param {string} type - Shape type (ex: 'rect', 'circle')\r\n   * @param {Object} options - Shape options\r\n   *      @param {(ShapeFillOption | string)} [options.fill] - ShapeFillOption or Shape foreground color (ex: '#fff', 'transparent') or ShapeFillOption object\r\n   *      @param {string} [options.stroke] - Shape outline color\r\n   *      @param {number} [options.strokeWidth] - Shape outline width\r\n   *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not\r\n   * @returns {Promise}\r\n   */\n\n\n  add(type, options) {\n    return new Promise(resolve => {\n      const canvas = this.getCanvas();\n\n      const extendOption = this._extendOptions(options);\n\n      const shapeObj = this._createInstance(type, extendOption);\n\n      const objectProperties = this.graphics.createObjectProperties(shapeObj);\n\n      this._bindEventOnShape(shapeObj);\n\n      canvas.add(shapeObj).setActiveObject(shapeObj);\n\n      this._resetPositionFillFilter(shapeObj);\n\n      resolve(objectProperties);\n    });\n  }\n  /**\r\n   * Change the shape\r\n   * @ignore\r\n   * @param {fabric.Object} shapeObj - Selected shape object on canvas\r\n   * @param {Object} options - Shape options\r\n   *      @param {(ShapeFillOption | string)} [options.fill] - {@link ShapeFillOption} or\r\n   *        Shape foreground color (ex: '#fff', 'transparent')\r\n   *      @param {string} [options.stroke] - Shape outline color\r\n   *      @param {number} [options.strokeWidth] - Shape outline width\r\n   *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not\r\n   * @returns {Promise}\r\n   */\n\n\n  change(shapeObj, options) {\n    return new Promise((resolve, reject) => {\n      if (!isShape(shapeObj)) {\n        reject(rejectMessages.unsupportedType);\n      }\n\n      const hasFillOption = getFillTypeFromOption(options.fill) === 'filter';\n      const {\n        canvasImage,\n        createStaticCanvas\n      } = this.graphics;\n      shapeObj.set(hasFillOption ? makeFabricFillOption(options, canvasImage, createStaticCanvas) : options);\n\n      if (hasFillOption) {\n        this._resetPositionFillFilter(shapeObj);\n      }\n\n      this.getCanvas().renderAll();\n      resolve();\n    });\n  }\n  /**\r\n   * make fill property for user event\r\n   * @param {fabric.Object} shapeObj - fabric object\r\n   * @returns {Object}\r\n   */\n\n\n  makeFillPropertyForUserEvent(shapeObj) {\n    const fillType = getFillTypeFromObject(shapeObj);\n    const fillProp = {};\n\n    if (fillType === SHAPE_FILL_TYPE.FILTER) {\n      const fillImage = getFillImageFromShape(shapeObj);\n      const filterOption = makeFilterOptionFromFabricImage(fillImage);\n      fillProp.type = fillType;\n      fillProp.filter = filterOption;\n    } else {\n      fillProp.type = SHAPE_FILL_TYPE.COLOR;\n      fillProp.color = shapeObj.fill || 'transparent';\n    }\n\n    return fillProp;\n  }\n  /**\r\n   * Copy object handling.\r\n   * @param {fabric.Object} shapeObj - Shape object\r\n   * @param {fabric.Object} originalShapeObj - Shape object\r\n   */\n\n\n  processForCopiedObject(shapeObj, originalShapeObj) {\n    this._bindEventOnShape(shapeObj);\n\n    if (getFillTypeFromObject(shapeObj) === 'filter') {\n      const fillImage = getFillImageFromShape(originalShapeObj);\n      const filterOption = makeFilterOptionFromFabricImage(fillImage);\n      const newStaticCanvas = this.graphics.createStaticCanvas();\n      shapeObj.set(makeFillPatternForFilter(this.graphics.canvasImage, filterOption, newStaticCanvas));\n\n      this._resetPositionFillFilter(shapeObj);\n    }\n  }\n  /**\r\n   * Create the instance of shape\r\n   * @param {string} type - Shape type\r\n   * @param {Object} options - Options to creat the shape\r\n   * @returns {fabric.Object} Shape instance\r\n   * @private\r\n   */\n\n\n  _createInstance(type, options) {\n    let instance;\n\n    switch (type) {\n      case 'rect':\n        instance = new fabric.Rect(options);\n        break;\n\n      case 'circle':\n        instance = new fabric.Ellipse(extend({\n          type: 'circle'\n        }, options));\n        break;\n\n      case 'triangle':\n        instance = new fabric.Triangle(options);\n        break;\n\n      default:\n        instance = {};\n    }\n\n    return instance;\n  }\n  /**\r\n   * Get the options to create the shape\r\n   * @param {Object} options - Options to creat the shape\r\n   * @returns {Object} Shape options\r\n   * @private\r\n   */\n\n\n  _extendOptions(options) {\n    const selectionStyles = fObjectOptions.SELECTION_STYLE;\n    const {\n      canvasImage,\n      createStaticCanvas\n    } = this.graphics;\n    options = extend({}, SHAPE_INIT_OPTIONS, this._options, selectionStyles, options);\n    return makeFabricFillOption(options, canvasImage, createStaticCanvas);\n  }\n  /**\r\n   * Bind fabric events on the creating shape object\r\n   * @param {fabric.Object} shapeObj - Shape object\r\n   * @private\r\n   */\n\n\n  _bindEventOnShape(shapeObj) {\n    const self = this;\n    const canvas = this.getCanvas();\n    shapeObj.on({\n      added() {\n        self._shapeObj = this;\n        resizeHelper.setOrigins(self._shapeObj);\n      },\n\n      selected() {\n        self._isSelected = true;\n        self._shapeObj = this;\n        canvas.uniformScaling = true;\n        canvas.defaultCursor = 'default';\n        resizeHelper.setOrigins(self._shapeObj);\n      },\n\n      deselected() {\n        self._isSelected = false;\n        self._shapeObj = null;\n        canvas.defaultCursor = 'crosshair';\n        canvas.uniformScaling = false;\n      },\n\n      modified() {\n        const currentObj = self._shapeObj;\n        resizeHelper.adjustOriginToCenter(currentObj);\n        resizeHelper.setOrigins(currentObj);\n      },\n\n      modifiedInGroup(activeSelection) {\n        self._fillFilterRePositionInGroupSelection(shapeObj, activeSelection);\n      },\n\n      moving() {\n        self._resetPositionFillFilter(this);\n      },\n\n      rotating() {\n        self._resetPositionFillFilter(this);\n      },\n\n      scaling(fEvent) {\n        const pointer = canvas.getPointer(fEvent.e);\n        const currentObj = self._shapeObj;\n        canvas.setCursor('crosshair');\n        resizeHelper.resize(currentObj, pointer, true);\n\n        self._resetPositionFillFilter(this);\n      }\n\n    });\n  }\n  /**\r\n   * MouseDown event handler on canvas\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object\r\n   * @private\r\n   */\n\n\n  _onFabricMouseDown(fEvent) {\n    if (!fEvent.target) {\n      this._isSelected = false;\n      this._shapeObj = false;\n    }\n\n    if (!this._isSelected && !this._shapeObj) {\n      const canvas = this.getCanvas();\n      this._startPoint = canvas.getPointer(fEvent.e);\n      canvas.on({\n        'mouse:move': this._handlers.mousemove,\n        'mouse:up': this._handlers.mouseup\n      });\n    }\n  }\n  /**\r\n   * MouseDown event handler on canvas\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object\r\n   * @private\r\n   */\n\n\n  _onFabricMouseMove(fEvent) {\n    const canvas = this.getCanvas();\n    const pointer = canvas.getPointer(fEvent.e);\n    const startPointX = this._startPoint.x;\n    const startPointY = this._startPoint.y;\n    const width = startPointX - pointer.x;\n    const height = startPointY - pointer.y;\n    const shape = this._shapeObj;\n\n    if (!shape) {\n      this.add(this._type, {\n        left: startPointX,\n        top: startPointY,\n        width,\n        height\n      }).then(objectProps => {\n        this.fire(eventNames.ADD_OBJECT, objectProps);\n      });\n    } else {\n      this._shapeObj.set({\n        isRegular: this._withShiftKey\n      });\n\n      resizeHelper.resize(shape, pointer);\n      canvas.renderAll();\n\n      this._resetPositionFillFilter(shape);\n    }\n  }\n  /**\r\n   * MouseUp event handler on canvas\r\n   * @private\r\n   */\n\n\n  _onFabricMouseUp() {\n    const canvas = this.getCanvas();\n    const startPointX = this._startPoint.x;\n    const startPointY = this._startPoint.y;\n    const shape = this._shapeObj;\n\n    if (!shape) {\n      this.add(this._type, {\n        left: startPointX,\n        top: startPointY,\n        width: DEFAULT_WIDTH,\n        height: DEFAULT_HEIGHT\n      }).then(objectProps => {\n        this.fire(eventNames.ADD_OBJECT, objectProps);\n      });\n    } else if (shape) {\n      resizeHelper.adjustOriginToCenter(shape);\n      this.fire(eventNames.OBJECT_ADDED, this.graphics.createObjectProperties(shape));\n    }\n\n    canvas.off({\n      'mouse:move': this._handlers.mousemove,\n      'mouse:up': this._handlers.mouseup\n    });\n  }\n  /**\r\n   * Keydown event handler on document\r\n   * @param {KeyboardEvent} e - Event object\r\n   * @private\r\n   */\n\n\n  _onKeyDown(e) {\n    if (e.keyCode === KEY_CODES.SHIFT) {\n      this._withShiftKey = true;\n\n      if (this._shapeObj) {\n        this._shapeObj.isRegular = true;\n      }\n    }\n  }\n  /**\r\n   * Keyup event handler on document\r\n   * @param {KeyboardEvent} e - Event object\r\n   * @private\r\n   */\n\n\n  _onKeyUp(e) {\n    if (e.keyCode === KEY_CODES.SHIFT) {\n      this._withShiftKey = false;\n\n      if (this._shapeObj) {\n        this._shapeObj.isRegular = false;\n      }\n    }\n  }\n  /**\r\n   * Reset shape position and internal proportions in the filter type fill area.\r\n   * @param {fabric.Object} shapeObj - Shape object\r\n   * @private\r\n   */\n\n\n  _resetPositionFillFilter(shapeObj) {\n    if (getFillTypeFromObject(shapeObj) !== 'filter') {\n      return;\n    }\n\n    const {\n      patternSourceCanvas\n    } = getCustomProperty(shapeObj, 'patternSourceCanvas');\n    const fillImage = getFillImageFromShape(shapeObj);\n    const {\n      originalAngle\n    } = getCustomProperty(fillImage, 'originalAngle');\n\n    if (this.graphics.canvasImage.angle !== originalAngle) {\n      reMakePatternImageSource(shapeObj, this.graphics.canvasImage);\n    }\n\n    const {\n      originX,\n      originY\n    } = shapeObj;\n    resizeHelper.adjustOriginToCenter(shapeObj);\n    shapeObj.width *= shapeObj.scaleX;\n    shapeObj.height *= shapeObj.scaleY;\n    shapeObj.rx *= shapeObj.scaleX;\n    shapeObj.ry *= shapeObj.scaleY;\n    shapeObj.scaleX = 1;\n    shapeObj.scaleY = 1;\n    rePositionFilterTypeFillImage(shapeObj);\n    changeOrigin(shapeObj, {\n      originX,\n      originY\n    });\n    resetFillPatternCanvas(patternSourceCanvas);\n  }\n  /**\r\n   * Reset filter area position within group selection.\r\n   * @param {fabric.Object} shapeObj - Shape object\r\n   * @param {fabric.ActiveSelection} activeSelection - Shape object\r\n   * @private\r\n   */\n\n\n  _fillFilterRePositionInGroupSelection(shapeObj, activeSelection) {\n    if (activeSelection.scaleX !== 1 || activeSelection.scaleY !== 1) {\n      // This is necessary because the group's scale transition state affects the relative size of the fill area.\n      // The only way to reset the object transformation scale state to neutral.\n      // {@link https://github.com/fabricjs/fabric.js/issues/5372}\n      activeSelection.addWithUpdate();\n    }\n\n    const {\n      angle,\n      left,\n      top\n    } = shapeObj;\n    activeSelection.realizeTransform(shapeObj);\n\n    this._resetPositionFillFilter(shapeObj);\n\n    shapeObj.set({\n      angle,\n      left,\n      top\n    });\n  }\n\n}","map":{"version":3,"sources":["C:/Users/kkwan_000/Desktop/git/2017110269/minsung/src/js/component/shape.js"],"names":["fabric","Component","rejectMessages","eventNames","keyCodes","KEY_CODES","componentNames","fObjectOptions","SHAPE_DEFAULT_OPTIONS","SHAPE_FILL_TYPE","resizeHelper","getFillImageFromShape","rePositionFilterTypeFillImage","reMakePatternImageSource","makeFillPatternForFilter","makeFilterOptionFromFabricImage","resetFillPatternCanvas","Promise","changeOrigin","getCustomProperty","getFillTypeFromOption","getFillTypeFromObject","isShape","extend","SHAPE_INIT_OPTIONS","strokeWidth","stroke","fill","width","height","rx","ry","DEFAULT_TYPE","DEFAULT_WIDTH","DEFAULT_HEIGHT","makeFabricFillOption","options","canvasImage","createStaticCanvas","fillOption","fillType","color","extOption","newStaticCanvas","filter","Shape","constructor","graphics","SHAPE","_shapeObj","_type","_options","_isSelected","_startPoint","_withShiftKey","_handlers","mousedown","_onFabricMouseDown","bind","mousemove","_onFabricMouseMove","mouseup","_onFabricMouseUp","keydown","_onKeyDown","keyup","_onKeyUp","start","canvas","getCanvas","defaultCursor","selection","uniformScaling","on","util","addListener","document","end","off","removeListener","setStates","type","add","resolve","extendOption","_extendOptions","shapeObj","_createInstance","objectProperties","createObjectProperties","_bindEventOnShape","setActiveObject","_resetPositionFillFilter","change","reject","unsupportedType","hasFillOption","set","renderAll","makeFillPropertyForUserEvent","fillProp","FILTER","fillImage","filterOption","COLOR","processForCopiedObject","originalShapeObj","instance","Rect","Ellipse","Triangle","selectionStyles","SELECTION_STYLE","self","added","setOrigins","selected","deselected","modified","currentObj","adjustOriginToCenter","modifiedInGroup","activeSelection","_fillFilterRePositionInGroupSelection","moving","rotating","scaling","fEvent","pointer","getPointer","e","setCursor","resize","target","startPointX","x","startPointY","y","shape","left","top","then","objectProps","fire","ADD_OBJECT","isRegular","OBJECT_ADDED","keyCode","SHIFT","patternSourceCanvas","originalAngle","angle","originX","originY","scaleX","scaleY","addWithUpdate","realizeTransform"],"mappings":"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","sourcesContent":["/**\r\n * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>\r\n * @fileoverview Shape component\r\n */\r\nimport fabric from 'fabric';\r\nimport Component from '../interface/component';\r\nimport {\r\n  rejectMessages,\r\n  eventNames,\r\n  keyCodes as KEY_CODES,\r\n  componentNames,\r\n  fObjectOptions,\r\n  SHAPE_DEFAULT_OPTIONS,\r\n  SHAPE_FILL_TYPE,\r\n} from '../consts';\r\nimport resizeHelper from '../helper/shapeResizeHelper';\r\nimport {\r\n  getFillImageFromShape,\r\n  rePositionFilterTypeFillImage,\r\n  reMakePatternImageSource,\r\n  makeFillPatternForFilter,\r\n  makeFilterOptionFromFabricImage,\r\n  resetFillPatternCanvas,\r\n} from '../helper/shapeFilterFillHelper';\r\nimport {\r\n  Promise,\r\n  changeOrigin,\r\n  getCustomProperty,\r\n  getFillTypeFromOption,\r\n  getFillTypeFromObject,\r\n  isShape,\r\n} from '../util';\r\nimport { extend } from 'tui-code-snippet';\r\n\r\nconst SHAPE_INIT_OPTIONS = extend(\r\n  {\r\n    strokeWidth: 1,\r\n    stroke: '#000000',\r\n    fill: '#ffffff',\r\n    width: 1,\r\n    height: 1,\r\n    rx: 0,\r\n    ry: 0,\r\n  },\r\n  SHAPE_DEFAULT_OPTIONS\r\n);\r\n\r\nconst DEFAULT_TYPE = 'rect';\r\nconst DEFAULT_WIDTH = 20;\r\nconst DEFAULT_HEIGHT = 20;\r\n\r\n/**\r\n * Make fill option\r\n * @param {Object} options - Options to create the shape\r\n * @param {Object.Image} canvasImage - canvas background image\r\n * @param {Function} createStaticCanvas - static canvas creater\r\n * @returns {Object} - shape option\r\n * @private\r\n */\r\nfunction makeFabricFillOption(options, canvasImage, createStaticCanvas) {\r\n  const fillOption = options.fill;\r\n  const fillType = getFillTypeFromOption(options.fill);\r\n  let fill = fillOption;\r\n\r\n  if (fillOption.color) {\r\n    fill = fillOption.color;\r\n  }\r\n\r\n  let extOption = null;\r\n  if (fillType === 'filter') {\r\n    const newStaticCanvas = createStaticCanvas();\r\n    extOption = makeFillPatternForFilter(canvasImage, fillOption.filter, newStaticCanvas);\r\n  } else {\r\n    extOption = { fill };\r\n  }\r\n\r\n  return extend({}, options, extOption);\r\n}\r\n\r\n/**\r\n * Shape\r\n * @class Shape\r\n * @param {Graphics} graphics - Graphics instance\r\n * @extends {Component}\r\n * @ignore\r\n */\r\nexport default class Shape extends Component {\r\n  constructor(graphics) {\r\n    super(componentNames.SHAPE, graphics);\r\n\r\n    /**\r\n     * Object of The drawing shape\r\n     * @type {fabric.Object}\r\n     * @private\r\n     */\r\n    this._shapeObj = null;\r\n\r\n    /**\r\n     * Type of the drawing shape\r\n     * @type {string}\r\n     * @private\r\n     */\r\n    this._type = DEFAULT_TYPE;\r\n\r\n    /**\r\n     * Options to draw the shape\r\n     * @type {Object}\r\n     * @private\r\n     */\r\n    this._options = extend({}, SHAPE_INIT_OPTIONS);\r\n\r\n    /**\r\n     * Whether the shape object is selected or not\r\n     * @type {boolean}\r\n     * @private\r\n     */\r\n    this._isSelected = false;\r\n\r\n    /**\r\n     * Pointer for drawing shape (x, y)\r\n     * @type {Object}\r\n     * @private\r\n     */\r\n    this._startPoint = {};\r\n\r\n    /**\r\n     * Using shortcut on drawing shape\r\n     * @type {boolean}\r\n     * @private\r\n     */\r\n    this._withShiftKey = false;\r\n\r\n    /**\r\n     * Event handler list\r\n     * @type {Object}\r\n     * @private\r\n     */\r\n    this._handlers = {\r\n      mousedown: this._onFabricMouseDown.bind(this),\r\n      mousemove: this._onFabricMouseMove.bind(this),\r\n      mouseup: this._onFabricMouseUp.bind(this),\r\n      keydown: this._onKeyDown.bind(this),\r\n      keyup: this._onKeyUp.bind(this),\r\n    };\r\n  }\r\n\r\n  /**\r\n   * Start to draw the shape on canvas\r\n   * @ignore\r\n   */\r\n  start() {\r\n    const canvas = this.getCanvas();\r\n\r\n    this._isSelected = false;\r\n\r\n    canvas.defaultCursor = 'crosshair';\r\n    canvas.selection = false;\r\n    canvas.uniformScaling = true;\r\n    canvas.on({\r\n      'mouse:down': this._handlers.mousedown,\r\n    });\r\n\r\n    fabric.util.addListener(document, 'keydown', this._handlers.keydown);\r\n    fabric.util.addListener(document, 'keyup', this._handlers.keyup);\r\n  }\r\n\r\n  /**\r\n   * End to draw the shape on canvas\r\n   * @ignore\r\n   */\r\n  end() {\r\n    const canvas = this.getCanvas();\r\n\r\n    this._isSelected = false;\r\n\r\n    canvas.defaultCursor = 'default';\r\n\r\n    canvas.selection = true;\r\n    canvas.uniformScaling = false;\r\n    canvas.off({\r\n      'mouse:down': this._handlers.mousedown,\r\n    });\r\n\r\n    fabric.util.removeListener(document, 'keydown', this._handlers.keydown);\r\n    fabric.util.removeListener(document, 'keyup', this._handlers.keyup);\r\n  }\r\n\r\n  /**\r\n   * Set states of the current drawing shape\r\n   * @ignore\r\n   * @param {string} type - Shape type (ex: 'rect', 'circle')\r\n   * @param {Object} [options] - Shape options\r\n   *      @param {(ShapeFillOption | string)} [options.fill] - {@link ShapeFillOption} or\r\n   *        Shape foreground color (ex: '#fff', 'transparent')\r\n   *      @param {string} [options.stoke] - Shape outline color\r\n   *      @param {number} [options.strokeWidth] - Shape outline width\r\n   *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)\r\n   */\r\n  setStates(type, options) {\r\n    this._type = type;\r\n\r\n    if (options) {\r\n      this._options = extend(this._options, options);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Add the shape\r\n   * @ignore\r\n   * @param {string} type - Shape type (ex: 'rect', 'circle')\r\n   * @param {Object} options - Shape options\r\n   *      @param {(ShapeFillOption | string)} [options.fill] - ShapeFillOption or Shape foreground color (ex: '#fff', 'transparent') or ShapeFillOption object\r\n   *      @param {string} [options.stroke] - Shape outline color\r\n   *      @param {number} [options.strokeWidth] - Shape outline width\r\n   *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not\r\n   * @returns {Promise}\r\n   */\r\n  add(type, options) {\r\n    return new Promise((resolve) => {\r\n      const canvas = this.getCanvas();\r\n      const extendOption = this._extendOptions(options);\r\n\r\n      const shapeObj = this._createInstance(type, extendOption);\r\n      const objectProperties = this.graphics.createObjectProperties(shapeObj);\r\n\r\n      this._bindEventOnShape(shapeObj);\r\n\r\n      canvas.add(shapeObj).setActiveObject(shapeObj);\r\n\r\n      this._resetPositionFillFilter(shapeObj);\r\n\r\n      resolve(objectProperties);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Change the shape\r\n   * @ignore\r\n   * @param {fabric.Object} shapeObj - Selected shape object on canvas\r\n   * @param {Object} options - Shape options\r\n   *      @param {(ShapeFillOption | string)} [options.fill] - {@link ShapeFillOption} or\r\n   *        Shape foreground color (ex: '#fff', 'transparent')\r\n   *      @param {string} [options.stroke] - Shape outline color\r\n   *      @param {number} [options.strokeWidth] - Shape outline width\r\n   *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)\r\n   *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)\r\n   *      @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not\r\n   * @returns {Promise}\r\n   */\r\n  change(shapeObj, options) {\r\n    return new Promise((resolve, reject) => {\r\n      if (!isShape(shapeObj)) {\r\n        reject(rejectMessages.unsupportedType);\r\n      }\r\n      const hasFillOption = getFillTypeFromOption(options.fill) === 'filter';\r\n      const { canvasImage, createStaticCanvas } = this.graphics;\r\n\r\n      shapeObj.set(\r\n        hasFillOption ? makeFabricFillOption(options, canvasImage, createStaticCanvas) : options\r\n      );\r\n\r\n      if (hasFillOption) {\r\n        this._resetPositionFillFilter(shapeObj);\r\n      }\r\n\r\n      this.getCanvas().renderAll();\r\n      resolve();\r\n    });\r\n  }\r\n\r\n  /**\r\n   * make fill property for user event\r\n   * @param {fabric.Object} shapeObj - fabric object\r\n   * @returns {Object}\r\n   */\r\n  makeFillPropertyForUserEvent(shapeObj) {\r\n    const fillType = getFillTypeFromObject(shapeObj);\r\n    const fillProp = {};\r\n\r\n    if (fillType === SHAPE_FILL_TYPE.FILTER) {\r\n      const fillImage = getFillImageFromShape(shapeObj);\r\n      const filterOption = makeFilterOptionFromFabricImage(fillImage);\r\n\r\n      fillProp.type = fillType;\r\n      fillProp.filter = filterOption;\r\n    } else {\r\n      fillProp.type = SHAPE_FILL_TYPE.COLOR;\r\n      fillProp.color = shapeObj.fill || 'transparent';\r\n    }\r\n\r\n    return fillProp;\r\n  }\r\n\r\n  /**\r\n   * Copy object handling.\r\n   * @param {fabric.Object} shapeObj - Shape object\r\n   * @param {fabric.Object} originalShapeObj - Shape object\r\n   */\r\n  processForCopiedObject(shapeObj, originalShapeObj) {\r\n    this._bindEventOnShape(shapeObj);\r\n\r\n    if (getFillTypeFromObject(shapeObj) === 'filter') {\r\n      const fillImage = getFillImageFromShape(originalShapeObj);\r\n      const filterOption = makeFilterOptionFromFabricImage(fillImage);\r\n      const newStaticCanvas = this.graphics.createStaticCanvas();\r\n\r\n      shapeObj.set(\r\n        makeFillPatternForFilter(this.graphics.canvasImage, filterOption, newStaticCanvas)\r\n      );\r\n      this._resetPositionFillFilter(shapeObj);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Create the instance of shape\r\n   * @param {string} type - Shape type\r\n   * @param {Object} options - Options to creat the shape\r\n   * @returns {fabric.Object} Shape instance\r\n   * @private\r\n   */\r\n  _createInstance(type, options) {\r\n    let instance;\r\n\r\n    switch (type) {\r\n      case 'rect':\r\n        instance = new fabric.Rect(options);\r\n        break;\r\n      case 'circle':\r\n        instance = new fabric.Ellipse(\r\n          extend(\r\n            {\r\n              type: 'circle',\r\n            },\r\n            options\r\n          )\r\n        );\r\n        break;\r\n      case 'triangle':\r\n        instance = new fabric.Triangle(options);\r\n        break;\r\n      default:\r\n        instance = {};\r\n    }\r\n\r\n    return instance;\r\n  }\r\n\r\n  /**\r\n   * Get the options to create the shape\r\n   * @param {Object} options - Options to creat the shape\r\n   * @returns {Object} Shape options\r\n   * @private\r\n   */\r\n  _extendOptions(options) {\r\n    const selectionStyles = fObjectOptions.SELECTION_STYLE;\r\n    const { canvasImage, createStaticCanvas } = this.graphics;\r\n\r\n    options = extend({}, SHAPE_INIT_OPTIONS, this._options, selectionStyles, options);\r\n\r\n    return makeFabricFillOption(options, canvasImage, createStaticCanvas);\r\n  }\r\n\r\n  /**\r\n   * Bind fabric events on the creating shape object\r\n   * @param {fabric.Object} shapeObj - Shape object\r\n   * @private\r\n   */\r\n  _bindEventOnShape(shapeObj) {\r\n    const self = this;\r\n    const canvas = this.getCanvas();\r\n\r\n    shapeObj.on({\r\n      added() {\r\n        self._shapeObj = this;\r\n        resizeHelper.setOrigins(self._shapeObj);\r\n      },\r\n      selected() {\r\n        self._isSelected = true;\r\n        self._shapeObj = this;\r\n        canvas.uniformScaling = true;\r\n        canvas.defaultCursor = 'default';\r\n        resizeHelper.setOrigins(self._shapeObj);\r\n      },\r\n      deselected() {\r\n        self._isSelected = false;\r\n        self._shapeObj = null;\r\n        canvas.defaultCursor = 'crosshair';\r\n        canvas.uniformScaling = false;\r\n      },\r\n      modified() {\r\n        const currentObj = self._shapeObj;\r\n\r\n        resizeHelper.adjustOriginToCenter(currentObj);\r\n        resizeHelper.setOrigins(currentObj);\r\n      },\r\n      modifiedInGroup(activeSelection) {\r\n        self._fillFilterRePositionInGroupSelection(shapeObj, activeSelection);\r\n      },\r\n      moving() {\r\n        self._resetPositionFillFilter(this);\r\n      },\r\n      rotating() {\r\n        self._resetPositionFillFilter(this);\r\n      },\r\n      scaling(fEvent) {\r\n        const pointer = canvas.getPointer(fEvent.e);\r\n        const currentObj = self._shapeObj;\r\n\r\n        canvas.setCursor('crosshair');\r\n        resizeHelper.resize(currentObj, pointer, true);\r\n\r\n        self._resetPositionFillFilter(this);\r\n      },\r\n    });\r\n  }\r\n\r\n  /**\r\n   * MouseDown event handler on canvas\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object\r\n   * @private\r\n   */\r\n  _onFabricMouseDown(fEvent) {\r\n    if (!fEvent.target) {\r\n      this._isSelected = false;\r\n      this._shapeObj = false;\r\n    }\r\n\r\n    if (!this._isSelected && !this._shapeObj) {\r\n      const canvas = this.getCanvas();\r\n      this._startPoint = canvas.getPointer(fEvent.e);\r\n\r\n      canvas.on({\r\n        'mouse:move': this._handlers.mousemove,\r\n        'mouse:up': this._handlers.mouseup,\r\n      });\r\n    }\r\n  }\r\n\r\n  /**\r\n   * MouseDown event handler on canvas\r\n   * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object\r\n   * @private\r\n   */\r\n  _onFabricMouseMove(fEvent) {\r\n    const canvas = this.getCanvas();\r\n    const pointer = canvas.getPointer(fEvent.e);\r\n    const startPointX = this._startPoint.x;\r\n    const startPointY = this._startPoint.y;\r\n    const width = startPointX - pointer.x;\r\n    const height = startPointY - pointer.y;\r\n    const shape = this._shapeObj;\r\n\r\n    if (!shape) {\r\n      this.add(this._type, {\r\n        left: startPointX,\r\n        top: startPointY,\r\n        width,\r\n        height,\r\n      }).then((objectProps) => {\r\n        this.fire(eventNames.ADD_OBJECT, objectProps);\r\n      });\r\n    } else {\r\n      this._shapeObj.set({\r\n        isRegular: this._withShiftKey,\r\n      });\r\n\r\n      resizeHelper.resize(shape, pointer);\r\n      canvas.renderAll();\r\n\r\n      this._resetPositionFillFilter(shape);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * MouseUp event handler on canvas\r\n   * @private\r\n   */\r\n  _onFabricMouseUp() {\r\n    const canvas = this.getCanvas();\r\n    const startPointX = this._startPoint.x;\r\n    const startPointY = this._startPoint.y;\r\n    const shape = this._shapeObj;\r\n\r\n    if (!shape) {\r\n      this.add(this._type, {\r\n        left: startPointX,\r\n        top: startPointY,\r\n        width: DEFAULT_WIDTH,\r\n        height: DEFAULT_HEIGHT,\r\n      }).then((objectProps) => {\r\n        this.fire(eventNames.ADD_OBJECT, objectProps);\r\n      });\r\n    } else if (shape) {\r\n      resizeHelper.adjustOriginToCenter(shape);\r\n      this.fire(eventNames.OBJECT_ADDED, this.graphics.createObjectProperties(shape));\r\n    }\r\n\r\n    canvas.off({\r\n      'mouse:move': this._handlers.mousemove,\r\n      'mouse:up': this._handlers.mouseup,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Keydown event handler on document\r\n   * @param {KeyboardEvent} e - Event object\r\n   * @private\r\n   */\r\n  _onKeyDown(e) {\r\n    if (e.keyCode === KEY_CODES.SHIFT) {\r\n      this._withShiftKey = true;\r\n\r\n      if (this._shapeObj) {\r\n        this._shapeObj.isRegular = true;\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Keyup event handler on document\r\n   * @param {KeyboardEvent} e - Event object\r\n   * @private\r\n   */\r\n  _onKeyUp(e) {\r\n    if (e.keyCode === KEY_CODES.SHIFT) {\r\n      this._withShiftKey = false;\r\n\r\n      if (this._shapeObj) {\r\n        this._shapeObj.isRegular = false;\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Reset shape position and internal proportions in the filter type fill area.\r\n   * @param {fabric.Object} shapeObj - Shape object\r\n   * @private\r\n   */\r\n  _resetPositionFillFilter(shapeObj) {\r\n    if (getFillTypeFromObject(shapeObj) !== 'filter') {\r\n      return;\r\n    }\r\n\r\n    const { patternSourceCanvas } = getCustomProperty(shapeObj, 'patternSourceCanvas');\r\n\r\n    const fillImage = getFillImageFromShape(shapeObj);\r\n    const { originalAngle } = getCustomProperty(fillImage, 'originalAngle');\r\n\r\n    if (this.graphics.canvasImage.angle !== originalAngle) {\r\n      reMakePatternImageSource(shapeObj, this.graphics.canvasImage);\r\n    }\r\n    const { originX, originY } = shapeObj;\r\n\r\n    resizeHelper.adjustOriginToCenter(shapeObj);\r\n\r\n    shapeObj.width *= shapeObj.scaleX;\r\n    shapeObj.height *= shapeObj.scaleY;\r\n    shapeObj.rx *= shapeObj.scaleX;\r\n    shapeObj.ry *= shapeObj.scaleY;\r\n    shapeObj.scaleX = 1;\r\n    shapeObj.scaleY = 1;\r\n\r\n    rePositionFilterTypeFillImage(shapeObj);\r\n\r\n    changeOrigin(shapeObj, {\r\n      originX,\r\n      originY,\r\n    });\r\n\r\n    resetFillPatternCanvas(patternSourceCanvas);\r\n  }\r\n\r\n  /**\r\n   * Reset filter area position within group selection.\r\n   * @param {fabric.Object} shapeObj - Shape object\r\n   * @param {fabric.ActiveSelection} activeSelection - Shape object\r\n   * @private\r\n   */\r\n  _fillFilterRePositionInGroupSelection(shapeObj, activeSelection) {\r\n    if (activeSelection.scaleX !== 1 || activeSelection.scaleY !== 1) {\r\n      // This is necessary because the group's scale transition state affects the relative size of the fill area.\r\n      // The only way to reset the object transformation scale state to neutral.\r\n      // {@link https://github.com/fabricjs/fabric.js/issues/5372}\r\n      activeSelection.addWithUpdate();\r\n    }\r\n\r\n    const { angle, left, top } = shapeObj;\r\n\r\n    activeSelection.realizeTransform(shapeObj);\r\n    this._resetPositionFillFilter(shapeObj);\r\n\r\n    shapeObj.set({\r\n      angle,\r\n      left,\r\n      top,\r\n    });\r\n  }\r\n}\r\n"]},"metadata":{},"sourceType":"module"}