{"version":3,"file":"Canvas.min.mjs","sources":["../../../src/canvas/Canvas.ts"],"sourcesContent":["import { classRegistry } from '../ClassRegistry';\nimport { NONE } from '../constants';\nimport type {\n  CanvasEvents,\n  DragEventData,\n  ObjectEvents,\n  TEventsExtraData,\n  TPointerEvent,\n  TPointerEventNames,\n  Transform,\n} from '../EventTypeDefs';\nimport { Point } from '../Point';\nimport type { ActiveSelection } from '../shapes/ActiveSelection';\nimport type { Group } from '../shapes/Group';\nimport type { IText } from '../shapes/IText/IText';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { isTouchEvent, stopEvent } from '../util/dom_event';\nimport { getDocumentFromElement, getWindowFromElement } from '../util/dom_misc';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { isActiveSelection } from '../util/typeAssertions';\nimport type { CanvasOptions, TCanvasOptions } from './CanvasOptions';\nimport { SelectableCanvas } from './SelectableCanvas';\nimport { TextEditingManager } from './TextEditingManager';\n\nconst addEventOptions = { passive: false } as EventListenerOptions;\n\nconst getEventPoints = (canvas: Canvas, e: TPointerEvent) => {\n  const viewportPoint = canvas.getViewportPoint(e);\n  const scenePoint = canvas.getScenePoint(e);\n  return {\n    viewportPoint,\n    scenePoint,\n    pointer: viewportPoint,\n    absolutePointer: scenePoint,\n  };\n};\n\n// just to be clear, the utils are now deprecated and those are here exactly as minifier helpers\n// because el.addEventListener can't me be minified while a const yes and we use it 47 times in this file.\n// few bytes but why give it away.\nconst addListener = (\n  el: HTMLElement | Document,\n  ...args: Parameters<HTMLElement['addEventListener']>\n) => el.addEventListener(...args);\nconst removeListener = (\n  el: HTMLElement | Document,\n  ...args: Parameters<HTMLElement['removeEventListener']>\n) => el.removeEventListener(...args);\n\nconst syntheticEventConfig = {\n  mouse: {\n    in: 'over',\n    out: 'out',\n    targetIn: 'mouseover',\n    targetOut: 'mouseout',\n    canvasIn: 'mouse:over',\n    canvasOut: 'mouse:out',\n  },\n  drag: {\n    in: 'enter',\n    out: 'leave',\n    targetIn: 'dragenter',\n    targetOut: 'dragleave',\n    canvasIn: 'drag:enter',\n    canvasOut: 'drag:leave',\n  },\n} as const;\n\ntype TSyntheticEventContext = {\n  mouse: { e: TPointerEvent };\n  drag: DragEventData;\n};\n\nexport class Canvas extends SelectableCanvas implements CanvasOptions {\n  /**\n   * Contains the id of the touch event that owns the fabric transform\n   * @type Number\n   * @private\n   */\n  declare mainTouchId?: number;\n\n  declare enablePointerEvents: boolean;\n\n  /**\n   * Holds a reference to a setTimeout timer for event synchronization\n   * @type number\n   * @private\n   */\n  private declare _willAddMouseDown: number;\n\n  /**\n   * Holds a reference to an object on the canvas that is receiving the drag over event.\n   * @type FabricObject\n   * @private\n   */\n  private declare _draggedoverTarget?: FabricObject;\n\n  /**\n   * Holds a reference to an object on the canvas from where the drag operation started\n   * @type FabricObject\n   * @private\n   */\n  private declare _dragSource?: FabricObject;\n\n  /**\n   * Holds a reference to an object on the canvas that is the current drop target\n   * May differ from {@link _draggedoverTarget}\n   * @todo inspect whether {@link _draggedoverTarget} and {@link _dropTarget} should be merged somehow\n   * @type FabricObject\n   * @private\n   */\n  private declare _dropTarget: FabricObject<ObjectEvents> | undefined;\n\n  /**\n   * a boolean that keeps track of the click state during a cycle of mouse down/up.\n   * If a mouse move occurs it becomes false.\n   * Is true by default, turns false on mouse move.\n   * Used to determine if a mouseUp is a click\n   */\n  private _isClick: boolean;\n\n  textEditingManager = new TextEditingManager(this);\n\n  constructor(el?: string | HTMLCanvasElement, options: TCanvasOptions = {}) {\n    super(el, options);\n    // bind event handlers\n    (\n      [\n        '_onMouseDown',\n        '_onTouchStart',\n        '_onMouseMove',\n        '_onMouseUp',\n        '_onTouchEnd',\n        '_onResize',\n        // '_onGesture',\n        // '_onDrag',\n        // '_onShake',\n        // '_onLongPress',\n        // '_onOrientationChange',\n        '_onMouseWheel',\n        '_onMouseOut',\n        '_onMouseEnter',\n        '_onContextMenu',\n        '_onClick',\n        '_onDragStart',\n        '_onDragEnd',\n        '_onDragProgress',\n        '_onDragOver',\n        '_onDragEnter',\n        '_onDragLeave',\n        '_onDrop',\n      ] as (keyof this)[]\n    ).forEach((eventHandler) => {\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n      this[eventHandler] = (this[eventHandler] as Function).bind(this);\n    });\n    // register event handlers\n    this.addOrRemove(addListener, 'add');\n  }\n\n  /**\n   * return an event prefix pointer or mouse.\n   * @private\n   */\n  private _getEventPrefix() {\n    return this.enablePointerEvents ? 'pointer' : 'mouse';\n  }\n\n  addOrRemove(functor: any, _eventjsFunctor: 'add' | 'remove') {\n    const canvasElement = this.upperCanvasEl,\n      eventTypePrefix = this._getEventPrefix();\n    functor(getWindowFromElement(canvasElement), 'resize', this._onResize);\n    functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n    functor(\n      canvasElement,\n      `${eventTypePrefix}move`,\n      this._onMouseMove,\n      addEventOptions,\n    );\n    functor(canvasElement, `${eventTypePrefix}out`, this._onMouseOut);\n    functor(canvasElement, `${eventTypePrefix}enter`, this._onMouseEnter);\n    functor(canvasElement, 'wheel', this._onMouseWheel);\n    functor(canvasElement, 'contextmenu', this._onContextMenu);\n    functor(canvasElement, 'click', this._onClick);\n    // decide if to remove in fabric 7.0\n    functor(canvasElement, 'dblclick', this._onClick);\n    functor(canvasElement, 'dragstart', this._onDragStart);\n    functor(canvasElement, 'dragend', this._onDragEnd);\n    functor(canvasElement, 'dragover', this._onDragOver);\n    functor(canvasElement, 'dragenter', this._onDragEnter);\n    functor(canvasElement, 'dragleave', this._onDragLeave);\n    functor(canvasElement, 'drop', this._onDrop);\n    if (!this.enablePointerEvents) {\n      functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);\n    }\n    // if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {\n    //   eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture);\n    //   eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag);\n    //   eventjs[eventjsFunctor](\n    //     canvasElement,\n    //     'orientation',\n    //     this._onOrientationChange\n    //   );\n    //   eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake);\n    //   eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress);\n    // }\n  }\n\n  /**\n   * Removes all event listeners, used when disposing the instance\n   */\n  removeListeners() {\n    this.addOrRemove(removeListener, 'remove');\n    // if you dispose on a mouseDown, before mouse up, you need to clean document to...\n    const eventTypePrefix = this._getEventPrefix();\n    const doc = getDocumentFromElement(this.upperCanvasEl);\n    removeListener(\n      doc,\n      `${eventTypePrefix}up`,\n      this._onMouseUp as EventListener,\n    );\n    removeListener(\n      doc,\n      'touchend',\n      this._onTouchEnd as EventListener,\n      addEventOptions,\n    );\n    removeListener(\n      doc,\n      `${eventTypePrefix}move`,\n      this._onMouseMove as EventListener,\n      addEventOptions,\n    );\n    removeListener(\n      doc,\n      'touchmove',\n      this._onMouseMove as EventListener,\n      addEventOptions,\n    );\n    clearTimeout(this._willAddMouseDown);\n  }\n\n  /**\n   * @private\n   * @param {Event} [e] Event object fired on wheel event\n   */\n  private _onMouseWheel(e: MouseEvent) {\n    this.__onMouseWheel(e);\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mousedown\n   */\n  private _onMouseOut(e: TPointerEvent) {\n    const target = this._hoveredTarget;\n    const shared = {\n      e,\n      ...getEventPoints(this, e),\n    };\n    this.fire('mouse:out', { ...shared, target });\n    this._hoveredTarget = undefined;\n    target && target.fire('mouseout', { ...shared });\n    this._hoveredTargets.forEach((nestedTarget) => {\n      this.fire('mouse:out', { ...shared, target: nestedTarget });\n      nestedTarget && nestedTarget.fire('mouseout', { ...shared });\n    });\n    this._hoveredTargets = [];\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mouseenter\n   */\n  private _onMouseEnter(e: TPointerEvent) {\n    // This find target and consequent 'mouse:over' is used to\n    // clear old instances on hovered target.\n    // calling findTarget has the side effect of killing target.__corner.\n    // as a short term fix we are not firing this if we are currently transforming.\n    // as a long term fix we need to separate the action of finding a target with the\n    // side effects we added to it.\n    if (!this._currentTransform && !this.findTarget(e)) {\n      this.fire('mouse:over', {\n        e,\n        ...getEventPoints(this, e),\n      });\n      this._hoveredTarget = undefined;\n      this._hoveredTargets = [];\n    }\n  }\n\n  /**\n   * supports native like text dragging\n   * @private\n   * @param {DragEvent} e\n   */\n  private _onDragStart(e: DragEvent) {\n    this._isClick = false;\n    const activeObject = this.getActiveObject();\n    if (activeObject && activeObject.onDragStart(e)) {\n      this._dragSource = activeObject;\n      const options = { e, target: activeObject };\n      this.fire('dragstart', options);\n      activeObject.fire('dragstart', options);\n      addListener(\n        this.upperCanvasEl,\n        'drag',\n        this._onDragProgress as EventListener,\n      );\n      return;\n    }\n    stopEvent(e);\n  }\n\n  /**\n   * First we clear top context where the effects are being rendered.\n   * Then we render the effects.\n   * Doing so will render the correct effect for all cases including an overlap between `source` and `target`.\n   * @private\n   */\n  private _renderDragEffects(\n    e: DragEvent,\n    source?: FabricObject,\n    target?: FabricObject,\n  ) {\n    let dirty = false;\n    // clear top context\n    const dropTarget = this._dropTarget;\n    if (dropTarget && dropTarget !== source && dropTarget !== target) {\n      dropTarget.clearContextTop();\n      dirty = true;\n    }\n    source?.clearContextTop();\n    target !== source && target?.clearContextTop();\n    // render effects\n    const ctx = this.contextTop;\n    ctx.save();\n    ctx.transform(...this.viewportTransform);\n    if (source) {\n      ctx.save();\n      source.transform(ctx);\n      source.renderDragSourceEffect(e);\n      ctx.restore();\n      dirty = true;\n    }\n    if (target) {\n      ctx.save();\n      target.transform(ctx);\n      target.renderDropTargetEffect(e);\n      ctx.restore();\n      dirty = true;\n    }\n    ctx.restore();\n    dirty && (this.contextTopDirty = true);\n  }\n\n  /**\n   * supports native like text dragging\n   * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag\n   * @private\n   * @param {DragEvent} e\n   */\n  private _onDragEnd(e: DragEvent) {\n    const didDrop = !!e.dataTransfer && e.dataTransfer.dropEffect !== NONE,\n      dropTarget = didDrop ? this._activeObject : undefined,\n      options = {\n        e,\n        target: this._dragSource as FabricObject,\n        subTargets: this.targets,\n        dragSource: this._dragSource as FabricObject,\n        didDrop,\n        dropTarget: dropTarget as FabricObject,\n      };\n    removeListener(\n      this.upperCanvasEl,\n      'drag',\n      this._onDragProgress as EventListener,\n    );\n    this.fire('dragend', options);\n    this._dragSource && this._dragSource.fire('dragend', options);\n    delete this._dragSource;\n    // we need to call mouse up synthetically because the browser won't\n    this._onMouseUp(e);\n  }\n\n  /**\n   * fire `drag` event on canvas and drag source\n   * @private\n   * @param {DragEvent} e\n   */\n  private _onDragProgress(e: DragEvent) {\n    const options = {\n      e,\n      target: this._dragSource as FabricObject | undefined,\n      dragSource: this._dragSource as FabricObject | undefined,\n      dropTarget: this._draggedoverTarget as FabricObject,\n    };\n    this.fire('drag', options);\n    this._dragSource && this._dragSource.fire('drag', options);\n  }\n\n  /**\n   * As opposed to {@link findTarget} we want the top most object to be returned w/o the active object cutting in line.\n   * Override at will\n   */\n  protected findDragTargets(e: DragEvent) {\n    this.targets = [];\n    const target = this._searchPossibleTargets(\n      this.getSearchTargets(),\n      this.getViewportPoint(e),\n    );\n    return {\n      target,\n      targets: [...this.targets],\n    };\n  }\n\n  /**\n   * prevent default to allow drop event to be fired\n   * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#specifying_drop_targets\n   * @private\n   * @param {DragEvent} [e] Event object fired on Event.js shake\n   */\n  private _onDragOver(e: DragEvent) {\n    const eventType = 'dragover';\n    const { target, targets } = this.findDragTargets(e);\n    const dragSource = this._dragSource as FabricObject;\n    const options = {\n      e,\n      target,\n      subTargets: targets,\n      dragSource,\n      canDrop: false,\n      dropTarget: undefined,\n    };\n    let dropTarget;\n    //  fire on canvas\n    this.fire(eventType, options);\n    //  make sure we fire dragenter events before dragover\n    //  if dragleave is needed, object will not fire dragover so we don't need to trouble ourselves with it\n    this._fireEnterLeaveEvents(target, options);\n    if (target) {\n      if (target.canDrop(e)) {\n        dropTarget = target;\n      }\n      target.fire(eventType, options);\n    }\n    //  propagate the event to subtargets\n    for (let i = 0; i < targets.length; i++) {\n      const subTarget = targets[i];\n      // accept event only if previous targets didn't (the accepting target calls `preventDefault` to inform that the event is taken)\n      // TODO: verify if those should loop in inverse order then?\n      // what is the order of subtargets?\n      if (subTarget.canDrop(e)) {\n        dropTarget = subTarget;\n      }\n      subTarget.fire(eventType, options);\n    }\n    //  render drag effects now that relations between source and target is clear\n    this._renderDragEffects(e, dragSource, dropTarget);\n    this._dropTarget = dropTarget;\n  }\n\n  /**\n   * fire `dragleave` on `dragover` targets\n   * @private\n   * @param {Event} [e] Event object fired on Event.js shake\n   */\n  private _onDragEnter(e: DragEvent) {\n    const { target, targets } = this.findDragTargets(e);\n    const options = {\n      e,\n      target,\n      subTargets: targets,\n      dragSource: this._dragSource,\n    };\n    this.fire('dragenter', options);\n    //  fire dragenter on targets\n    this._fireEnterLeaveEvents(target, options);\n  }\n\n  /**\n   * fire `dragleave` on `dragover` targets\n   * @private\n   * @param {Event} [e] Event object fired on Event.js shake\n   */\n  private _onDragLeave(e: DragEvent) {\n    const options = {\n      e,\n      target: this._draggedoverTarget,\n      subTargets: this.targets,\n      dragSource: this._dragSource,\n    };\n    this.fire('dragleave', options);\n\n    //  fire dragleave on targets\n    this._fireEnterLeaveEvents(undefined, options);\n    this._renderDragEffects(e, this._dragSource);\n    this._dropTarget = undefined;\n    //  clear targets\n    this.targets = [];\n    this._hoveredTargets = [];\n  }\n\n  /**\n   * `drop:before` is a an event that allows you to schedule logic\n   * before the `drop` event. Prefer `drop` event always, but if you need\n   * to run some drop-disabling logic on an event, since there is no way\n   * to handle event handlers ordering, use `drop:before`\n   * @private\n   * @param {Event} e\n   */\n  private _onDrop(e: DragEvent) {\n    const { target, targets } = this.findDragTargets(e);\n    const options = this._basicEventHandler('drop:before', {\n      e,\n      target,\n      subTargets: targets,\n      dragSource: this._dragSource,\n      ...getEventPoints(this, e),\n    });\n    //  will be set by the drop target\n    options.didDrop = false;\n    //  will be set by the drop target, used in case options.target refuses the drop\n    options.dropTarget = undefined;\n    //  fire `drop`\n    this._basicEventHandler('drop', options);\n    //  inform canvas of the drop\n    //  we do this because canvas was unaware of what happened at the time the `drop` event was fired on it\n    //  use for side effects\n    this.fire('drop:after', options);\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mousedown\n   */\n  private _onContextMenu(e: TPointerEvent): false {\n    const target = this.findTarget(e),\n      subTargets = this.targets || [];\n    const options = this._basicEventHandler('contextmenu:before', {\n      e,\n      target,\n      subTargets,\n    });\n    // TODO: this line is silly because the dev can subscribe to the event and prevent it themselves\n    this.stopContextMenu && stopEvent(e);\n    this._basicEventHandler('contextmenu', options);\n    return false;\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mousedown\n   */\n  private _onClick(e: TPointerEvent) {\n    const clicks = e.detail;\n    if (clicks > 3 || clicks < 2) return;\n    this._cacheTransformEventData(e);\n    clicks == 2 && e.type === 'dblclick' && this._onDblClick(e);\n    clicks == 3 && this._handleEvent(e, 'tripleclick');\n    this._resetTransformEventData();\n  }\n\n  /**\n   * Double-click to select the child nodes of the locked group\n   * @param e\n   */\n  private _onDblClick(e: TPointerEvent) {\n    if (this.dblClickLock(e)) {\n      // Immediately select the clicked child object after locking\n      this._resetTransformEventData();\n      this.__onMouseDown(e);\n      this.__onMouseUp(e);\n      return;\n    }\n    this._handleEvent(e, 'dblclick');\n  }\n\n  /**\n   * Return a the id of an event.\n   * returns either the pointerId or the identifier or 0 for the mouse event\n   * @private\n   * @param {Event} evt Event object\n   */\n  getPointerId(evt: TouchEvent | PointerEvent): number {\n    const changedTouches = (evt as TouchEvent).changedTouches;\n\n    if (changedTouches) {\n      return changedTouches[0] && changedTouches[0].identifier;\n    }\n\n    if (this.enablePointerEvents) {\n      return (evt as PointerEvent).pointerId;\n    }\n\n    return -1;\n  }\n\n  /**\n   * Determines if an event has the id of the event that is considered main\n   * @private\n   * @param {evt} event Event object\n   */\n  _isMainEvent(evt: TPointerEvent): boolean {\n    if ((evt as PointerEvent).isPrimary === true) {\n      return true;\n    }\n    if ((evt as PointerEvent).isPrimary === false) {\n      return false;\n    }\n    if (evt.type === 'touchend' && (evt as TouchEvent).touches.length === 0) {\n      return true;\n    }\n    if ((evt as TouchEvent).changedTouches) {\n      return (\n        (evt as TouchEvent).changedTouches[0].identifier === this.mainTouchId\n      );\n    }\n    return true;\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mousedown\n   */\n  _onTouchStart(e: TouchEvent) {\n    // we will prevent scrolling if allowTouchScrolling is not enabled and\n    let shouldPreventScrolling = !this.allowTouchScrolling;\n    const currentActiveObject = this._activeObject;\n    if (this.mainTouchId === undefined) {\n      this.mainTouchId = this.getPointerId(e);\n    }\n    this.__onMouseDown(e);\n    // after executing fabric logic for mouse down let's see\n    // if we didn't change target or if we are drawing\n    // we want to prevent scrolling anyway\n    if (\n      this.isDrawingMode ||\n      (currentActiveObject && this._target === currentActiveObject)\n    ) {\n      shouldPreventScrolling = true;\n    }\n    // prevent default, will block scrolling from start\n    shouldPreventScrolling && e.preventDefault();\n    this._resetTransformEventData();\n    const canvasElement = this.upperCanvasEl,\n      eventTypePrefix = this._getEventPrefix();\n    const doc = getDocumentFromElement(canvasElement);\n    addListener(\n      doc,\n      'touchend',\n      this._onTouchEnd as EventListener,\n      addEventOptions,\n    );\n    // if we scroll don't register the touch move event\n    shouldPreventScrolling &&\n      addListener(\n        doc,\n        'touchmove',\n        this._onMouseMove as EventListener,\n        addEventOptions,\n      );\n    // Unbind mousedown to prevent double triggers from touch devices\n    removeListener(\n      canvasElement,\n      `${eventTypePrefix}down`,\n      this._onMouseDown as EventListener,\n    );\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mousedown\n   */\n  _onMouseDown(e: TPointerEvent) {\n    this.__onMouseDown(e);\n    this._resetTransformEventData();\n    const canvasElement = this.upperCanvasEl,\n      eventTypePrefix = this._getEventPrefix();\n    removeListener(\n      canvasElement,\n      `${eventTypePrefix}move`,\n      this._onMouseMove as EventListener,\n      addEventOptions,\n    );\n    const doc = getDocumentFromElement(canvasElement);\n    addListener(doc, `${eventTypePrefix}up`, this._onMouseUp as EventListener);\n    addListener(\n      doc,\n      `${eventTypePrefix}move`,\n      this._onMouseMove as EventListener,\n      addEventOptions,\n    );\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mousedown\n   */\n  _onTouchEnd(e: TouchEvent) {\n    if (e.touches.length > 0) {\n      // if there are still touches stop here\n      return;\n    }\n    this.__onMouseUp(e);\n    this._resetTransformEventData();\n    delete this.mainTouchId;\n    const eventTypePrefix = this._getEventPrefix();\n    const doc = getDocumentFromElement(this.upperCanvasEl);\n    removeListener(\n      doc,\n      'touchend',\n      this._onTouchEnd as EventListener,\n      addEventOptions,\n    );\n    removeListener(\n      doc,\n      'touchmove',\n      this._onMouseMove as EventListener,\n      addEventOptions,\n    );\n    if (this._willAddMouseDown) {\n      clearTimeout(this._willAddMouseDown);\n    }\n    this._willAddMouseDown = setTimeout(() => {\n      // Wait 400ms before rebinding mousedown to prevent double triggers\n      // from touch devices\n      addListener(\n        this.upperCanvasEl,\n        `${eventTypePrefix}down`,\n        this._onMouseDown as EventListener,\n      );\n      this._willAddMouseDown = 0;\n    }, 400) as unknown as number;\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mouseup\n   */\n  _onMouseUp(e: TPointerEvent) {\n    this.__onMouseUp(e);\n    this._resetTransformEventData();\n    const canvasElement = this.upperCanvasEl,\n      eventTypePrefix = this._getEventPrefix();\n    if (this._isMainEvent(e)) {\n      const doc = getDocumentFromElement(this.upperCanvasEl);\n      removeListener(\n        doc,\n        `${eventTypePrefix}up`,\n        this._onMouseUp as EventListener,\n      );\n      removeListener(\n        doc,\n        `${eventTypePrefix}move`,\n        this._onMouseMove as EventListener,\n        addEventOptions,\n      );\n      addListener(\n        canvasElement,\n        `${eventTypePrefix}move`,\n        this._onMouseMove as EventListener,\n        addEventOptions,\n      );\n    }\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mousemove\n   */\n  _onMouseMove(e: TPointerEvent) {\n    const activeObject = this.getActiveObject();\n    !this.allowTouchScrolling &&\n      (!activeObject ||\n        // a drag event sequence is started by the active object flagging itself on mousedown / mousedown:before\n        // we must not prevent the event's default behavior in order for the window to start dragging\n        !activeObject.shouldStartDragging(e)) &&\n      e.preventDefault &&\n      e.preventDefault();\n    this.__onMouseMove(e);\n  }\n\n  /**\n   * @private\n   */\n  _onResize() {\n    this.calcOffset();\n    this._resetTransformEventData();\n  }\n\n  /**\n   * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n   * @private\n   * @param {Object} target\n   */\n  _shouldRender(target: FabricObject | undefined) {\n    const activeObject = this.getActiveObject();\n    // if just one of them is available or if they are both but are different objects\n    // this covers: switch of target, from target to no target, selection of target\n    // multiSelection with key and mouse\n    return (\n      !!activeObject !== !!target ||\n      (activeObject && target && activeObject !== target)\n    );\n  }\n\n  /**\n   * Method that defines the actions when mouse is released on canvas.\n   * The method resets the currentTransform parameters, store the image corner\n   * position in the image object and render the canvas on top.\n   * @private\n   * @param {Event} e Event object fired on mouseup\n   */\n  __onMouseUp(e: TPointerEvent) {\n    this._cacheTransformEventData(e);\n    this._handleEvent(e, 'up:before');\n\n    const transform = this._currentTransform;\n    const isClick = this._isClick;\n    const target = this._target;\n\n    // if right/middle click just fire events and return\n    // target undefined will make the _handleEvent search the target\n    const { button } = e as MouseEvent;\n    if (button) {\n      ((this.fireMiddleClick && button === 1) ||\n        (this.fireRightClick && button === 2)) &&\n        this._handleEvent(e, 'up');\n      this._resetTransformEventData();\n      return;\n    }\n\n    if (this.isDrawingMode && this._isCurrentlyDrawing) {\n      this._onMouseUpInDrawingMode(e);\n      return;\n    }\n\n    if (!this._isMainEvent(e)) {\n      return;\n    }\n    let shouldRender = false;\n    if (transform) {\n      this._finalizeCurrentTransform(e);\n      shouldRender = transform.actionPerformed;\n    }\n    if (!isClick) {\n      const targetWasActive = target === this._activeObject;\n      this.handleSelection(e);\n      if (!shouldRender) {\n        shouldRender =\n          this._shouldRender(target) ||\n          (!targetWasActive && target === this._activeObject);\n      }\n    }\n    let pointer, corner;\n    if (target) {\n      const found = target.findControl(\n        this.getViewportPoint(e),\n        isTouchEvent(e),\n      );\n      const { key, control } = found || {};\n      corner = key;\n      if (\n        target.selectable &&\n        target !== this._activeObject &&\n        target.activeOn === 'up'\n      ) {\n        this.setActiveObject(target, e);\n        shouldRender = true;\n      } else if (control) {\n        const mouseUpHandler = control.getMouseUpHandler(e, target, control);\n        if (mouseUpHandler) {\n          pointer = this.getScenePoint(e);\n          mouseUpHandler.call(control, e, transform!, pointer.x, pointer.y);\n        }\n      }\n      target.isMoving = false;\n    }\n    // if we are ending up a transform on a different control or a new object\n    // fire the original mouse up from the corner that started the transform\n    if (\n      transform &&\n      (transform.target !== target || transform.corner !== corner)\n    ) {\n      const originalControl =\n          transform.target && transform.target.controls[transform.corner],\n        originalMouseUpHandler =\n          originalControl &&\n          originalControl.getMouseUpHandler(\n            e,\n            transform.target,\n            originalControl,\n          );\n      pointer = pointer || this.getScenePoint(e);\n      originalMouseUpHandler &&\n        originalMouseUpHandler.call(\n          originalControl,\n          e,\n          transform,\n          pointer.x,\n          pointer.y,\n        );\n    }\n    this._setCursorFromEvent(e, target);\n    this._handleEvent(e, 'up');\n    this._groupSelector = null;\n    this._currentTransform = null;\n    // reset the target information about which corner is selected\n    target && (target.__corner = undefined);\n    if (shouldRender) {\n      this.requestRenderAll();\n    } else if (!isClick && !(this._activeObject as IText)?.isEditing) {\n      this.renderTop();\n    }\n    // 框选不改变locked对象，不框选时如果没有点击到可以锁定组，设置锁定组为null\n    if (isClick && !this.getActiveObject()) this.isolatedObject = null;\n  }\n\n  _basicEventHandler<T extends keyof (CanvasEvents | ObjectEvents)>(\n    eventType: T,\n    options: (CanvasEvents & ObjectEvents)[T],\n  ) {\n    const { target, subTargets = [] } = options as {\n      target?: FabricObject;\n      subTargets: FabricObject[];\n    };\n    this.fire(eventType, options);\n    target && target.fire(eventType, options);\n    for (let i = 0; i < subTargets.length; i++) {\n      subTargets[i] !== target && subTargets[i].fire(eventType, options);\n    }\n    return options;\n  }\n\n  /**\n   * @private\n   * Handle event firing for target and subtargets\n   * @param {TPointerEvent} e event from mouse\n   * @param {TPointerEventNames} eventType\n   */\n  _handleEvent<T extends TPointerEventNames>(\n    e: TPointerEvent,\n    eventType: T,\n    extraData?: TEventsExtraData[T],\n  ) {\n    const target = this._target,\n      targets = this.targets || [],\n      options: CanvasEvents[`mouse:${T}`] = {\n        e,\n        target,\n        subTargets: targets,\n        ...getEventPoints(this, e),\n        transform: this._currentTransform,\n        ...(eventType === 'up:before' || eventType === 'up'\n          ? {\n              isClick: this._isClick,\n              currentTarget: this.findTarget(e),\n              // set by the preceding `findTarget` call\n              currentSubTargets: this.targets,\n            }\n          : {}),\n        ...(eventType === 'down:before' || eventType === 'down'\n          ? extraData\n          : {}),\n      } as CanvasEvents[`mouse:${T}`];\n    this.fire(`mouse:${eventType}`, options);\n    // this may be a little be more complicated of what we want to handle\n    target && target.fire(`mouse${eventType}`, options);\n    for (let i = 0; i < targets.length; i++) {\n      targets[i] !== target && targets[i].fire(`mouse${eventType}`, options);\n    }\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mousedown\n   */\n  _onMouseDownInDrawingMode(e: TPointerEvent) {\n    this._isCurrentlyDrawing = true;\n    if (this.getActiveObject()) {\n      this.discardActiveObject(e);\n      this.requestRenderAll();\n    }\n    // TODO: this is a scene point so it should be renamed\n    const pointer = this.getScenePoint(e);\n    this.freeDrawingBrush &&\n      this.freeDrawingBrush.onMouseDown(pointer, { e, pointer });\n    this._handleEvent(e, 'down', { alreadySelected: false });\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mousemove\n   */\n  _onMouseMoveInDrawingMode(e: TPointerEvent) {\n    if (this._isCurrentlyDrawing) {\n      const pointer = this.getScenePoint(e);\n      this.freeDrawingBrush &&\n        this.freeDrawingBrush.onMouseMove(pointer, {\n          e,\n          // this is an absolute pointer, the naming is wrong\n          pointer,\n        });\n    }\n    this.setCursor(this.freeDrawingCursor);\n    this._handleEvent(e, 'move');\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event object fired on mouseup\n   */\n  _onMouseUpInDrawingMode(e: TPointerEvent) {\n    const pointer = this.getScenePoint(e);\n    if (this.freeDrawingBrush) {\n      this._isCurrentlyDrawing = !!this.freeDrawingBrush.onMouseUp({\n        e: e,\n        // this is an absolute pointer, the naming is wrong\n        pointer,\n      });\n    } else {\n      this._isCurrentlyDrawing = false;\n    }\n    this._handleEvent(e, 'up');\n  }\n\n  /**\n   * Change to other isolated object when click on current group's parent\n   * When click empty space or other object, cancel isolated state\n   * @param e\n   * @returns\n   */\n  switchIsolateObject(e: TPointerEvent) {\n    if (!this.isolatedObject || this._fixedSearchTargets) return false;\n    let isolatedObject = null;\n    if (this.isolatedObject.parent) {\n      const parents = [];\n      let currentObj = this.isolatedObject;\n      while (currentObj.parent) {\n        parents.push(currentObj.parent);\n        currentObj = currentObj.parent;\n      }\n      // check topmost parent, if it was clicked, find the nearest child object to isolate\n      const topmostParent = parents[parents.length - 1];\n      this.setFixedSearchTargets([topmostParent]);\n      let target = this.findTarget(e);\n      // parent was clicked\n      if (target) {\n        parents.some((parent) => {\n          this.setFixedSearchTargets(parent.getObjects());\n          target = this.findTarget(e);\n          if (target) {\n            isolatedObject = parent;\n            // The newly created group object has its child node coords initialized, otherwise it cannot be selected.\n            parent.getObjects().forEach((o) => {\n              o.setCoords();\n            });\n            return true;\n          }\n          return false;\n        });\n      }\n      this.setFixedSearchTargets(null);\n    }\n    if (isolatedObject) {\n      this.isolatedObject = isolatedObject;\n      // use __onMouseDown select other object immediately after unlocking\n      this._resetTransformEventData();\n      this.__onMouseDown(e);\n      return true;\n    }\n    return false;\n  }\n\n  /**\n   * Method that defines the actions when mouse is clicked on canvas.\n   * The method inits the currentTransform parameters and renders all the\n   * canvas so the current image can be placed on the top canvas and the rest\n   * in on the container one.\n   * @private\n   * @param {Event} e Event object fired on mousedown\n   */\n  __onMouseDown(e: TPointerEvent) {\n    this._isClick = true;\n    this._cacheTransformEventData(e);\n    this._handleEvent(e, 'down:before');\n\n    let target: FabricObject | undefined = this._target;\n    let alreadySelected = !!target && target === this._activeObject;\n    // if right/middle click just fire events\n    const { button } = e as MouseEvent;\n    if (button) {\n      ((this.fireMiddleClick && button === 1) ||\n        (this.fireRightClick && button === 2)) &&\n        this._handleEvent(e, 'down', {\n          alreadySelected,\n        });\n      this._resetTransformEventData();\n      return;\n    }\n\n    if (this.isDrawingMode) {\n      this._onMouseDownInDrawingMode(e);\n      return;\n    }\n\n    if (!this._isMainEvent(e)) {\n      return;\n    }\n\n    // ignore if some object is being transformed at this moment\n    if (this._currentTransform) {\n      return;\n    }\n\n    let shouldRender = this._shouldRender(target);\n    let grouped = false;\n    if (this.handleMultiSelection(e, target)) {\n      // active object might have changed while grouping\n      target = this._activeObject;\n      grouped = true;\n      shouldRender = true;\n    } else if (this._shouldClearSelection(e, target)) {\n      const objs = this.getActiveObjects();\n      this.discardActiveObject(e);\n      // 多选取消，重置Coords， 防止无法再次选中\n      objs.forEach((obj) => obj.setCoords());\n      if (!target && this.switchIsolateObject(e)) {\n        return;\n      }\n    }\n    // we start a group selector rectangle if\n    // selection is enabled\n    // and there is no target, or the following 3 conditions are satisfied:\n    // target is not selectable ( otherwise we selected it )\n    // target is not editing\n    // target is not already selected ( otherwise we drag )\n    if (\n      this.selection &&\n      (!target ||\n        (!target.selectable &&\n          !(target as IText).isEditing &&\n          target !== this._activeObject))\n    ) {\n      const p = this.getScenePoint(e);\n      this._groupSelector = {\n        x: p.x,\n        y: p.y,\n        deltaY: 0,\n        deltaX: 0,\n      };\n    }\n\n    // check again because things could have changed\n    alreadySelected = !!target && target === this._activeObject;\n    if (target) {\n      if (target.selectable && target.activeOn === 'down') {\n        this.setActiveObject(target, e);\n      }\n      const handle = target.findControl(\n        this.getViewportPoint(e),\n        isTouchEvent(e),\n      );\n      if (target === this._activeObject && (handle || !grouped)) {\n        this._setupCurrentTransform(e, target, alreadySelected);\n        const control = handle ? handle.control : undefined,\n          pointer = this.getScenePoint(e),\n          mouseDownHandler =\n            control && control.getMouseDownHandler(e, target, control);\n        mouseDownHandler &&\n          mouseDownHandler.call(\n            control,\n            e,\n            this._currentTransform!,\n            pointer.x,\n            pointer.y,\n          );\n      }\n    }\n    //  we clear `_objectsToRender` in case of a change in order to repopulate it at rendering\n    //  run before firing the `down` event to give the dev a chance to populate it themselves\n    shouldRender && (this._objectsToRender = undefined);\n    this._handleEvent(e, 'down', { alreadySelected: alreadySelected });\n    // we must renderAll so that we update the visuals\n    shouldRender && this.requestRenderAll();\n  }\n\n  /**\n   * reset cache form common information needed during event processing\n   * @private\n   */\n  _resetTransformEventData() {\n    this._target = this._pointer = this._absolutePointer = undefined;\n  }\n\n  /**\n   * Cache common information needed during event processing\n   * @private\n   * @param {Event} e Event object fired on event\n   */\n  _cacheTransformEventData(e: TPointerEvent) {\n    // reset in order to avoid stale caching\n    this._resetTransformEventData();\n    this._pointer = this.getViewportPoint(e);\n    this._absolutePointer = sendPointToPlane(\n      this._pointer,\n      undefined,\n      this.viewportTransform,\n    );\n    this._target = this._currentTransform\n      ? this._currentTransform.target\n      : this.findTarget(e);\n  }\n\n  /**\n   * Method that defines the actions when mouse is hovering the canvas.\n   * The currentTransform parameter will define whether the user is rotating/scaling/translating\n   * an image or neither of them (only hovering). A group selection is also possible and would cancel\n   * all any other type of action.\n   * In case of an image transformation only the top canvas will be rendered.\n   * @private\n   * @param {Event} e Event object fired on mousemove\n   */\n  __onMouseMove(e: TPointerEvent) {\n    this._isClick = false;\n    this._cacheTransformEventData(e);\n    this._handleEvent(e, 'move:before');\n\n    if (this.isDrawingMode) {\n      this._onMouseMoveInDrawingMode(e);\n      return;\n    }\n\n    if (!this._isMainEvent(e)) {\n      return;\n    }\n\n    const groupSelector = this._groupSelector;\n\n    // We initially clicked in an empty area, so we draw a box for multiple selection\n    if (groupSelector) {\n      const pointer = this.getScenePoint(e);\n\n      groupSelector.deltaX = pointer.x - groupSelector.x;\n      groupSelector.deltaY = pointer.y - groupSelector.y;\n\n      this.renderTop();\n    } else if (!this._currentTransform) {\n      const target = this.findTarget(e);\n      this._setCursorFromEvent(e, target);\n      this._fireOverOutEvents(e, target);\n    } else {\n      this._transformObject(e);\n    }\n    this.textEditingManager.onMouseMove(e);\n    this._handleEvent(e, 'move');\n    this._resetTransformEventData();\n  }\n\n  /**\n   * Manage the mouseout, mouseover events for the fabric object on the canvas\n   * @param {Fabric.Object} target the target where the target from the mousemove event\n   * @param {Event} e Event object fired on mousemove\n   * @private\n   */\n  _fireOverOutEvents(e: TPointerEvent, target?: FabricObject) {\n    const _hoveredTarget = this._hoveredTarget,\n      _hoveredTargets = this._hoveredTargets,\n      targets = this.targets,\n      length = Math.max(_hoveredTargets.length, targets.length);\n\n    this.fireSyntheticInOutEvents('mouse', {\n      e,\n      target,\n      oldTarget: _hoveredTarget,\n      fireCanvas: true,\n    });\n    for (let i = 0; i < length; i++) {\n      this.fireSyntheticInOutEvents('mouse', {\n        e,\n        target: targets[i],\n        oldTarget: _hoveredTargets[i],\n      });\n    }\n    this._hoveredTarget = target;\n    this._hoveredTargets = this.targets.concat();\n  }\n\n  /**\n   * Manage the dragEnter, dragLeave events for the fabric objects on the canvas\n   * @param {Fabric.Object} target the target where the target from the onDrag event\n   * @param {Object} data Event object fired on dragover\n   * @private\n   */\n  _fireEnterLeaveEvents(target: FabricObject | undefined, data: DragEventData) {\n    const draggedoverTarget = this._draggedoverTarget,\n      _hoveredTargets = this._hoveredTargets,\n      targets = this.targets,\n      length = Math.max(_hoveredTargets.length, targets.length);\n\n    this.fireSyntheticInOutEvents('drag', {\n      ...data,\n      target,\n      oldTarget: draggedoverTarget,\n      fireCanvas: true,\n    });\n    for (let i = 0; i < length; i++) {\n      this.fireSyntheticInOutEvents('drag', {\n        ...data,\n        target: targets[i],\n        oldTarget: _hoveredTargets[i],\n      });\n    }\n    this._draggedoverTarget = target;\n  }\n\n  /**\n   * Manage the synthetic in/out events for the fabric objects on the canvas\n   * @param {Fabric.Object} target the target where the target from the supported events\n   * @param {Object} data Event object fired\n   * @param {Object} config configuration for the function to work\n   * @param {String} config.targetName property on the canvas where the old target is stored\n   * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out\n   * @param {String} config.evtOut name of the event to fire for out\n   * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in\n   * @param {String} config.evtIn name of the event to fire for in\n   * @private\n   */\n  fireSyntheticInOutEvents<T extends keyof TSyntheticEventContext>(\n    type: T,\n    {\n      target,\n      oldTarget,\n      fireCanvas,\n      e,\n      ...data\n    }: TSyntheticEventContext[T] & {\n      target?: FabricObject;\n      oldTarget?: FabricObject;\n      fireCanvas?: boolean;\n    },\n  ) {\n    const { targetIn, targetOut, canvasIn, canvasOut } =\n      syntheticEventConfig[type];\n    const targetChanged = oldTarget !== target;\n\n    if (oldTarget && targetChanged) {\n      const outOpt: CanvasEvents[typeof canvasOut] = {\n        ...data,\n        e,\n        target: oldTarget,\n        nextTarget: target,\n        ...getEventPoints(this, e),\n      };\n      fireCanvas && this.fire(canvasOut, outOpt);\n      oldTarget.fire(targetOut, outOpt);\n    }\n    if (target && targetChanged) {\n      const inOpt: CanvasEvents[typeof canvasIn] = {\n        ...data,\n        e,\n        target,\n        previousTarget: oldTarget,\n        ...getEventPoints(this, e),\n      };\n      fireCanvas && this.fire(canvasIn, inOpt);\n      target.fire(targetIn, inOpt);\n    }\n  }\n\n  /**\n   * Method that defines actions when an Event Mouse Wheel\n   * @param {Event} e Event object fired on mouseup\n   */\n  __onMouseWheel(e: TPointerEvent) {\n    this._cacheTransformEventData(e);\n    this._handleEvent(e, 'wheel');\n    this._resetTransformEventData();\n  }\n\n  /**\n   * @private\n   * @param {Event} e Event fired on mousemove\n   */\n  _transformObject(e: TPointerEvent) {\n    const scenePoint = this.getScenePoint(e),\n      transform = this._currentTransform!,\n      target = transform.target,\n      //  transform pointer to target's containing coordinate plane\n      //  both pointer and object should agree on every point\n      localPointer = target.group\n        ? sendPointToPlane(\n            scenePoint,\n            undefined,\n            target.group.calcTransformMatrix(),\n          )\n        : scenePoint;\n    transform.shiftKey = e.shiftKey;\n    transform.altKey = !!this.centeredKey && e[this.centeredKey];\n\n    this._performTransformAction(e, transform, localPointer);\n    transform.actionPerformed && this.requestRenderAll();\n  }\n\n  /**\n   * @private\n   */\n  _performTransformAction(\n    e: TPointerEvent,\n    transform: Transform,\n    pointer: Point,\n  ) {\n    const { action, actionHandler, target } = transform;\n\n    const actionPerformed =\n      !!actionHandler && actionHandler(e, transform, pointer.x, pointer.y);\n    actionPerformed && target.setCoords();\n\n    // this object could be created from the function in the control handlers\n    if (action === 'drag' && actionPerformed) {\n      transform.target.isMoving = true;\n      this.setCursor(transform.target.moveCursor || this.moveCursor);\n    }\n    transform.actionPerformed = transform.actionPerformed || actionPerformed;\n  }\n\n  /**\n   * Sets the cursor depending on where the canvas is being hovered.\n   * Note: very buggy in Opera\n   * @param {Event} e Event object\n   * @param {Object} target Object that the mouse is hovering, if so.\n   */\n  _setCursorFromEvent(e: TPointerEvent, target?: FabricObject) {\n    if (!target) {\n      this.setCursor(this.defaultCursor);\n      return;\n    }\n    let hoverCursor = target.hoverCursor || this.hoverCursor;\n    const activeSelection = isActiveSelection(this._activeObject)\n        ? this._activeObject\n        : null,\n      // only show proper corner when group selection is not active\n      corner =\n        (!activeSelection || target.group !== activeSelection) &&\n        // here we call findTargetCorner always with undefined for the touch parameter.\n        // we assume that if you are using a cursor you do not need to interact with\n        // the bigger touch area.\n        target.findControl(this.getViewportPoint(e));\n\n    if (!corner) {\n      if ((target as Group).subTargetCheck) {\n        // hoverCursor should come from top-most subTarget,\n        // so we walk the array backwards\n        this.targets\n          .concat()\n          .reverse()\n          .map((_target) => {\n            hoverCursor = _target.hoverCursor || hoverCursor;\n          });\n      }\n      this.setCursor(hoverCursor);\n    } else {\n      const control = corner.control;\n      this.setCursor(control.cursorStyleHandler(e, control, target));\n    }\n  }\n\n  /**\n   * ## Handles multiple selection\n   * - toggles `target` selection (selects/deselects `target` if it isn't/is selected respectively)\n   * - sets the active object in case it is not set or in case there is a single active object left under active selection.\n   * ---\n   * - If the active object is the active selection we add/remove `target` from it\n   * - If not, add the active object and `target` to the active selection and make it the active object.\n   * @private\n   * @param {TPointerEvent} e Event object\n   * @param {FabricObject} target target of event to select/deselect\n   * @returns true if grouping occurred\n   */\n  protected handleMultiSelection(e: TPointerEvent, target?: FabricObject) {\n    const activeObject = this._activeObject;\n    const isAS = isActiveSelection(activeObject);\n    if (\n      // check if an active object exists on canvas and if the user is pressing the `selectionKey` while canvas supports multi selection.\n      !!activeObject &&\n      this._isSelectionKeyPressed(e) &&\n      this.selection &&\n      // on top of that the user also has to hit a target that is selectable.\n      !!target &&\n      target.selectable &&\n      // group target and active object only if they are different objects\n      // else we try to find a subtarget of `ActiveSelection`\n      (activeObject !== target || isAS) &&\n      //  make sure `activeObject` and `target` aren't ancestors of each other in case `activeObject` is not `ActiveSelection`\n      // if it is then we want to remove `target` from it\n      (isAS ||\n        (!target.isDescendantOf(activeObject) &&\n          !activeObject.isDescendantOf(target))) &&\n      //  target accepts selection\n      !target.onSelect({ e }) &&\n      // make sure we are not on top of a control\n      !activeObject.getActiveControl()\n    ) {\n      if (isAS) {\n        const prevActiveObjects = activeObject.getObjects();\n        if (target === activeObject) {\n          const pointer = this.getViewportPoint(e);\n          target =\n            // first search under active selection for a target to add\n            // will search from top level to bottom\n            this.searchPossibleTargets(this.getSearchTargets(), pointer) ||\n            //  if not found, search active objects for a target to remove\n            this.searchPossibleTargets(prevActiveObjects, pointer);\n\n          // if nothing is found bail out\n          if (!target || !target.selectable) {\n            return false;\n          }\n        }\n        if (target.group === activeObject) {\n          // `target` is part of active selection => remove it\n          activeObject.remove(target);\n          target.setCoords();\n          this._hoveredTarget = target;\n          this._hoveredTargets = [...this.targets];\n          // if after removing an object we are left with one only...\n          if (activeObject.size() === 1) {\n            // activate last remaining object\n            // deselecting the active selection will remove the remaining object from it\n            this._setActiveObject(activeObject.item(0), e);\n          }\n        } else {\n          // `target` isn't part of active selection => add it\n          activeObject.multiSelectAdd(target);\n          this._hoveredTarget = activeObject;\n          this._hoveredTargets = [...this.targets];\n        }\n        this._fireSelectionEvents(prevActiveObjects, e);\n      } else {\n        (activeObject as IText).isEditing &&\n          (activeObject as IText).exitEditing();\n        // add the active object and the target to the active selection and set it as the active object\n        const klass =\n          classRegistry.getClass<typeof ActiveSelection>('ActiveSelection');\n        const newActiveSelection = new klass([], {\n          /**\n           * it is crucial to pass the canvas ref before calling {@link ActiveSelection#multiSelectAdd}\n           * since it uses {@link FabricObject#isInFrontOf} which relies on the canvas ref\n           */\n          canvas: this,\n        });\n        newActiveSelection.multiSelectAdd(activeObject, target);\n        this._hoveredTarget = newActiveSelection;\n        // ISSUE 4115: should we consider subTargets here?\n        // this._hoveredTargets = [];\n        // this._hoveredTargets = this.targets.concat();\n        this._setActiveObject(newActiveSelection, e);\n        this._fireSelectionEvents([activeObject], e);\n      }\n      return true;\n    }\n    return false;\n  }\n\n  /**\n   * ## Handles selection\n   * - selects objects that are contained in (and possibly intersecting) the selection bounding box\n   * - sets the active object\n   * ---\n   * runs on mouse up after a mouse move\n   */\n  protected handleSelection(e: TPointerEvent) {\n    if (!this.selection || !this._groupSelector) {\n      return false;\n    }\n    const { x, y, deltaX, deltaY } = this._groupSelector,\n      point1 = new Point(x, y),\n      point2 = point1.add(new Point(deltaX, deltaY)),\n      tl = point1.min(point2),\n      br = point1.max(point2),\n      size = br.subtract(tl);\n\n    const collectedObjects = this.collectObjects(\n      this.getSearchTargets(),\n      {\n        left: tl.x,\n        top: tl.y,\n        width: size.x,\n        height: size.y,\n      },\n      { includeIntersecting: !this.selectionFullyContained },\n    ) as FabricObject[];\n\n    const objects =\n      // though this method runs only after mouse move the pointer could do a mouse up on the same position as mouse down\n      // should it be handled as is?\n      point1.eq(point2)\n        ? collectedObjects[0]\n          ? [collectedObjects[0]]\n          : []\n        : collectedObjects.length > 1\n          ? collectedObjects\n              .filter((object) => !object.onSelect({ e }))\n              .reverse()\n          : // `setActiveObject` will call `onSelect(collectedObjects[0])` in this case\n            collectedObjects;\n\n    // set active object\n    if (objects.length === 1) {\n      // set as active object\n      this.setActiveObject(objects[0], e);\n    } else if (objects.length > 1) {\n      // add to active selection and make it the active object\n      const klass =\n        classRegistry.getClass<typeof ActiveSelection>('ActiveSelection');\n      this.setActiveObject(new klass(objects, { canvas: this }), e);\n    }\n\n    // cleanup\n    this._groupSelector = null;\n    return true;\n  }\n\n  /**\n   * @override clear {@link textEditingManager}\n   */\n  clear() {\n    this.textEditingManager.clear();\n    super.clear();\n  }\n\n  /**\n   * @override clear {@link textEditingManager}\n   */\n  destroy() {\n    this.removeListeners();\n    this.textEditingManager.dispose();\n    super.destroy();\n  }\n}\n"],"names":["addEventOptions","passive","getEventPoints","canvas","e","viewportPoint","getViewportPoint","scenePoint","getScenePoint","pointer","absolutePointer","addListener","el","_len","arguments","length","args","Array","_key","addEventListener","removeListener","_len2","_key2","removeEventListener","syntheticEventConfig","mouse","in","out","targetIn","targetOut","canvasIn","canvasOut","drag","Canvas","SelectableCanvas","constructor","super","undefined","_defineProperty","this","TextEditingManager","forEach","eventHandler","bind","addOrRemove","_getEventPrefix","enablePointerEvents","functor","_eventjsFunctor","canvasElement","upperCanvasEl","eventTypePrefix","getWindowFromElement","_onResize","_onMouseDown","_onMouseMove","_onMouseOut","_onMouseEnter","_onMouseWheel","_onContextMenu","_onClick","_onDragStart","_onDragEnd","_onDragOver","_onDragEnter","_onDragLeave","_onDrop","_onTouchStart","removeListeners","doc","getDocumentFromElement","_onMouseUp","_onTouchEnd","clearTimeout","_willAddMouseDown","__onMouseWheel","target","_hoveredTarget","shared","fire","_hoveredTargets","nestedTarget","_currentTransform","findTarget","_isClick","activeObject","getActiveObject","onDragStart","_dragSource","options","_onDragProgress","stopEvent","_renderDragEffects","source","dirty","dropTarget","_dropTarget","clearContextTop","ctx","contextTop","save","transform","viewportTransform","renderDragSourceEffect","restore","renderDropTargetEffect","contextTopDirty","didDrop","dataTransfer","dropEffect","NONE","_activeObject","subTargets","targets","dragSource","_draggedoverTarget","findDragTargets","_searchPossibleTargets","getSearchTargets","eventType","canDrop","_fireEnterLeaveEvents","i","subTarget","_basicEventHandler","stopContextMenu","clicks","detail","_cacheTransformEventData","type","_onDblClick","_handleEvent","_resetTransformEventData","dblClickLock","__onMouseDown","__onMouseUp","getPointerId","evt","changedTouches","identifier","pointerId","_isMainEvent","isPrimary","touches","mainTouchId","shouldPreventScrolling","allowTouchScrolling","currentActiveObject","isDrawingMode","_target","preventDefault","setTimeout","shouldStartDragging","__onMouseMove","calcOffset","_shouldRender","_this$_activeObject","isClick","button","fireMiddleClick","fireRightClick","_isCurrentlyDrawing","_onMouseUpInDrawingMode","corner","shouldRender","_finalizeCurrentTransform","actionPerformed","targetWasActive","handleSelection","found","findControl","isTouchEvent","key","control","selectable","activeOn","setActiveObject","mouseUpHandler","getMouseUpHandler","call","x","y","isMoving","originalControl","controls","originalMouseUpHandler","_setCursorFromEvent","_groupSelector","__corner","requestRenderAll","isEditing","renderTop","isolatedObject","extraData","currentTarget","currentSubTargets","_onMouseDownInDrawingMode","discardActiveObject","freeDrawingBrush","onMouseDown","alreadySelected","_onMouseMoveInDrawingMode","onMouseMove","setCursor","freeDrawingCursor","onMouseUp","switchIsolateObject","_fixedSearchTargets","parent","parents","currentObj","push","topmostParent","setFixedSearchTargets","some","getObjects","o","setCoords","grouped","handleMultiSelection","_shouldClearSelection","objs","getActiveObjects","obj","selection","p","deltaY","deltaX","handle","_setupCurrentTransform","mouseDownHandler","getMouseDownHandler","_objectsToRender","_pointer","_absolutePointer","sendPointToPlane","groupSelector","_transformObject","_fireOverOutEvents","textEditingManager","Math","max","fireSyntheticInOutEvents","oldTarget","fireCanvas","concat","data","draggedoverTarget","_ref","targetChanged","outOpt","nextTarget","inOpt","previousTarget","localPointer","group","calcTransformMatrix","shiftKey","altKey","centeredKey","_performTransformAction","action","actionHandler","moveCursor","defaultCursor","hoverCursor","activeSelection","isActiveSelection","cursorStyleHandler","subTargetCheck","reverse","map","isAS","_isSelectionKeyPressed","isDescendantOf","onSelect","getActiveControl","prevActiveObjects","searchPossibleTargets","remove","size","_setActiveObject","item","multiSelectAdd","_fireSelectionEvents","exitEditing","newActiveSelection","classRegistry","getClass","point1","Point","point2","add","tl","min","subtract","collectedObjects","collectObjects","left","top","width","height","includeIntersecting","selectionFullyContained","objects","eq","filter","object","klass","clear","destroy","dispose"],"mappings":"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"}