HEX
Server: Apache
System: Linux p3plzcpnl506847.prod.phx3.secureserver.net 4.18.0-553.54.1.lve.el8.x86_64 #1 SMP Wed Jun 4 13:01:13 UTC 2025 x86_64
User: slfopp7cb1df (5698090)
PHP: 8.1.34
Disabled: NONE
Upload Files
File: /home/slfopp7cb1df/public_html/sitepacket.com/src/client/src/controllers/eventController.js
import { getEventCoordinates, isMobile } from 'Editor/scripts/utilities'
import * as consts from 'Client/consts'

export default class EventController {
  store = undefined

  action = consts.ACTION_IDLE
  actionStart = consts.ACTION_IDLE

  eventCoordinates = { x: 0, y: 0 }
  eventCoordinatesStart = { x: 0, y: 0 }
  eventCoordinatesPrevious = { x: 0, y: 0 }
  eventDirection = undefined

  UIRects = []
  UIRectUnderEvent = undefined
  UIRectUnderEventStart = undefined
  UIClickedRect = undefined

  isEventOverTooltip = undefined
  isEventOverCanvas = undefined

  objectIndexUnderEvent = undefined
  objectIndexUnderEventPrevious = undefined
  objectIndexUnderEventStart = undefined
  objectIdClicked = undefined

  menuListItemIDUnderEvent = undefined
  menuListItemIDUnderEventPrevious = undefined

  mac = navigator.platform.toUpperCase().indexOf('MAC') >= 0
  ctrlKeyDown = false
  cmdKeyDown = false

  canPinch = false

  constructor(store) {
    this.store = store
    this.createEvents()
  }
  buildUIModel() {
    // This is the order in which the rects will be tested

    if (this.store.getAreTooltipsFullscreen()) {
      // this.UIRects[consts.RECT_BUTTON_CLOSE_TOOLTIP_FULLSCREEN] = () => { return this.store.getTooltipCloseButtonRect() }
      this.UIRects[consts.RECT_OPENED_FULLSCREEN_TOOLTIP] = () => {
        return this.store.getOpenedFullscreenTooltipRect()
      }
    }

    if (this.store.state.fullscreen.enable_fullscreen_mode) {
      this.UIRects[consts.RECT_BUTTON_FULLSCREEN] = () => {
        return this.store.getFullscreenButtonRect()
      }
    }

    if (this.store.state.zooming.enable_zooming) {
      if (this.store.state.zooming.enable_zoom_buttons) {
        this.UIRects[consts.RECT_BUTTON_ZOOM_IN] = () => {
          return this.store.getZoomInButtonRect()
        }
        this.UIRects[consts.RECT_BUTTON_ZOOM_OUT] = () => {
          return this.store.getZoomOutButtonRect()
        }
      }

      if (this.store.state.zooming.enable_navigator) {
        this.UIRects[consts.RECT_NAVIGATOR] = () => {
          return this.store.getNavigatorRect()
        }
      }
    }

    if (this.store.state.artboards.length > 1) {
      this.UIRects[consts.RECT_ARTBOARD_SELECT_MENU] = () => {
        return this.store.getArtboardSelectRect()
      }
    }

    if (this.store.state.object_list.enable_object_list) {
      this.UIRects[consts.RECT_MENU] = () => {
        return this.store.getMenuRect()
      }
      this.UIRects[consts.RECT_BUTTON_OPEN_MENU] = () => {
        return this.store.getOpenMenuButtonRect()
      }
      this.UIRects[consts.RECT_BUTTON_CLOSE_MENU] = () => {
        return this.store.getCloseMenuButtonRect()
      }
    }
  }
  createEvents() {
    this.boundHandleEventStart = this.handleEventStart.bind(this)
    this.boundHandleEventMove = this.handleEventMove.bind(this)
    this.boundHandleEventEnd = this.handleEventEnd.bind(this)
    this.boundHandleEventKeyDown = this.handleEventKeyDown.bind(this)
    this.boundHandleEventKeyUp = this.handleEventKeyUp.bind(this)
    this.boundHandleEventResize = this.handleEventResize.bind(this)
    this.boundHandleEventWheel = this.handleEventWheel.bind(this)
    this.boundHandleEventChange = this.handleEventChange.bind(this)

    if (isMobile()) {
      document.addEventListener('touchstart', this.boundHandleEventStart, { passive: false })
      document.addEventListener('touchmove', this.boundHandleEventMove, { passive: false })
      document.addEventListener('touchend', this.boundHandleEventEnd, { passive: false })
    } else {
      document.addEventListener('mousedown', this.boundHandleEventStart, { passive: false })
      document.addEventListener('mousemove', this.boundHandleEventMove, { passive: false })
      document.addEventListener('mouseup', this.boundHandleEventEnd, { passive: false })
    }

    document.addEventListener('keydown', this.boundHandleEventKeyDown, { passive: false })
    document.addEventListener('keyup', this.boundHandleEventKeyUp, { passive: false })
    document.addEventListener('wheel', this.boundHandleEventWheel, { passive: false })
    document.addEventListener('change', this.boundHandleEventChange, { passive: false })

    const resizeObserver = new ResizeObserver(this.boundHandleEventResize)
    resizeObserver.observe(this.store.getContainer().parentElement)
  }
  removeEvents() {
    if (isMobile()) {
      document.removeEventListener('touchstart', this.boundHandleEventStart, { passive: false })
      document.removeEventListener('touchmove', this.boundHandleEventMove, { passive: false })
      document.removeEventListener('touchend', this.boundHandleEventEnd, { passive: false })
    } else {
      document.removeEventListener('mousedown', this.boundHandleEventStart, { passive: false })
      document.removeEventListener('mousemove', this.boundHandleEventMove, { passive: false })
      document.removeEventListener('mouseup', this.boundHandleEventEnd, { passive: false })
    }

    document.removeEventListener('keydown', this.boundHandleEventKeyDown, { passive: false })
    document.removeEventListener('keyup', this.boundHandleEventKeyUp, { passive: false })
    document.removeEventListener('wheel', this.boundHandleEventWheel, { passive: false })
    document.removeEventListener('change', this.boundHandleEventChange, { passive: false })
    window.removeEventListener('resize', this.boundHandleEventResize, { passive: false })
  }

  handleEventStart(e) {
    this.updateFlagsAndVariables(e)
    this.doStartAction()
    this.doMenuStart(e)
  }
  handleEventMove(e) {
    this.updateFlagsAndVariables(e)
    if (this.doAction(e)) {
      this.objectIdUnderEventPrevious = false
      this.store.dispatch('unhighlightAllObjects')
      return
    }
    if (this.doMenuMove(e)) return
    this.doMouseOverObject(e)
  }
  async handleEventEnd(e) {
    this.updateFlagsAndVariables(e)
    if (this.doEndAction()) return
    if (await this.doMenuEnd(e)) return
    if (this.doClickUI(e)) return
    if (this.doClickObject()) return
  }
  handleEventKeyDown(e) {
    this.updateFlagsAndVariables(e)
  }
  handleEventKeyUp(e) {
    this.updateFlagsAndVariables(e)

    if (e.code == 'Escape') {
      this.store.dispatch('closeFullscreen')
    }

    if (document.querySelector(`[data-image-map-id="${this.store.getID()}"] input:focus`)) {
      this.store.dispatch('updateSearch', {
        searchString: document.querySelector(`[data-image-map-id="${this.store.getID()}"] input:focus`).value,
      })
    }
  }
  handleEventResize() {
    this.store.dispatch('beforeResize')
    this.store.dispatch('resize')
  }
  handleEventWheel(e) {
    this.updateFlagsAndVariables(e)

    // Never zoom if the mouse is over a UI element
    if (this.UIRectUnderEvent) return

    // Zooming
    if (this.isEventOverCanvas && this.store.state.zooming.enable_zooming) {
      if (this.store.state.zooming.hold_ctrl_to_zoom) {
        if ((this.mac && this.cmdKeyDown) || (!this.mac && this.ctrlKeyDown)) {
          this.doZoom(e)
        } else {
          this.store.dispatch('failedToZoom')
        }
      } else {
        this.doZoom(e)
      }
    }
  }
  handleEventChange(e) {
    if (
      e.target.classList.contains('imp-ui-layers-select') &&
      e.target.closest(`[data-image-map-id="${this.store.getID()}"]`)
    ) {
      this.store.dispatch('changeArtboard', { artboardId: e.target.value, zoomOut: true })
    }

    if (e.target.closest(`[data-image-map-id="${this.store.getID()}"] .imp-search-box-input-wrap`)) {
      this.store.dispatch('updateSearch', { searchString: e.target.value })
    }
  }

  updateFlagsAndVariables(e) {
    // Handle key press
    if (e.type == 'keydown' || e.type == 'keyup') {
      this.ctrlKeyDown = e.ctrlKey
      this.cmdKeyDown = e.metaKey
      return
    }

    // Store event coords
    this.eventCoordinates = getEventCoordinates(e)
    if (e.type == 'mousedown' || e.type == 'touchstart') this.eventCoordinatesStart = this.eventCoordinates

    // Is event over UI?
    this.UIRectUnderEvent = this.getUIRectNameUnderEvent(e)
    if (e.type == 'mousedown' || e.type == 'touchstart') this.UIRectUnderEventStart = this.UIRectUnderEvent
    this.UIClickedRect = this.UIRectUnderEvent === this.UIRectUnderEventStart ? this.UIRectUnderEvent : false
    this.menuListItemIDUnderEvent = this.getMenuListItemIdUnderEvent(e)

    // Is event in canvas?
    this.isEventOverCanvas = this.isPointInsideRect(this.eventCoordinates, this.getZoomedCanvasRect())

    // Is event over tooltip?
    this.isEventOverTooltip =
      this.store
        .getTooltipController()
        .isPointInsideVisibleTooltip({ x: this.eventCoordinates.x, y: this.eventCoordinates.y }) ||
      this.isEventOverVisibleTooltip(e)

    // Is event over an object?
    this.objectIdUnderEvent = this.getObjectIdUnderEvent(e)

    if (e.type == 'mousedown' || e.type == 'touchstart') this.objectIdUnderEventStart = this.objectIdUnderEvent
    this.objectIdClicked = this.objectIdUnderEvent === this.objectIdUnderEventStart ? this.objectIdUnderEvent : false
    if (e.type == 'mousemove' || e.type == 'touchmove') this.objectIdUnderEventStart = false

    // Can pinch?
    this.canPinch = this.getCanPinch(e)

    this.updateStickyTooltipsConfig()

    // Calculate mouse direction
    let dx = this.eventCoordinates.x - this.eventCoordinatesPrevious.x
    let dy = this.eventCoordinates.y - this.eventCoordinatesPrevious.y
    if (dx > 0 && Math.abs(dx) > Math.abs(dy)) this.eventDirection = consts.MOUSE_DIRECTION_RIGHT
    if (dx < 0 && Math.abs(dx) > Math.abs(dy)) this.eventDirection = consts.MOUSE_DIRECTION_LEFT
    if (dy > 0 && Math.abs(dy) > Math.abs(dx)) this.eventDirection = consts.MOUSE_DIRECTION_DOWN
    if (dy < 0 && Math.abs(dy) > Math.abs(dx)) this.eventDirection = consts.MOUSE_DIRECTION_UP

    // Store event coords for the next cycle
    this.eventCoordinatesPrevious = { ...this.eventCoordinates }
  }

  // Actions
  doStartAction() {
    if (this.UIRectUnderEvent === consts.RECT_NAVIGATOR) {
      this.actionStart = consts.ACTION_PAN_ON_NAVIGATOR
      return
    }

    if (this.UIRectUnderEvent) return

    if (this.canPinch) {
      this.actionStart = consts.ACTION_PINCH
      return
    }
    if (this.isEventOverCanvas) {
      this.actionStart = consts.ACTION_PAN
      return
    }
  }
  doAction(e) {
    if (this.actionStart === consts.ACTION_PINCH) {
      // console.log('Started doing pinch')
      this.action = consts.ACTION_PINCH
      this.store.dispatch('startPinch', { event: e })
    }
    if (this.actionStart === consts.ACTION_PAN_ON_NAVIGATOR) {
      // console.log('Started doing pan on navigator')
      this.action = consts.ACTION_PAN_ON_NAVIGATOR
    }
    if (this.actionStart === consts.ACTION_PAN) {
      // console.log('Started doing pan')
      this.action = consts.ACTION_PAN
      this.store.dispatch('startPan', { x: this.eventCoordinates.x, y: this.eventCoordinates.y })
    }

    this.actionStart = consts.ACTION_IDLE

    if (this.action === consts.ACTION_PINCH) {
      // console.log('Doing pinch')
      this.store.dispatch('pinch', { event: e })
      this.preventDefault(e)
      return true
    }
    if (this.action === consts.ACTION_PAN_ON_NAVIGATOR) {
      // console.log('Doing pan on navigator')
      this.store.dispatch('panOnNavigator', { x: this.eventCoordinates.x, y: this.eventCoordinates.y })
      this.preventDefault(e)
      return true
    }
    if (this.action === consts.ACTION_PAN) {
      // console.log('Doing pan')
      this.store.dispatch('pan', { x: this.eventCoordinates.x, y: this.eventCoordinates.y })
      // console.log(this.isPanLimitReached())
      if (!this.isPanLimitReached()) this.preventDefault(e)
      return true
    }

    return false
  }
  doEndAction() {
    this.actionStart = consts.ACTION_IDLE

    if (this.action == consts.ACTION_PINCH) {
      if (!this.canPinch) {
        this.action = consts.ACTION_IDLE
      }

      if (this.isEventOverCanvas && !this.UIRectUnderEvent) {
        // transition to panning
        this.action = consts.ACTION_PAN
        this.store.dispatch('startPan', this.eventCoordinates)
      }

      return true
    }

    if (this.action !== consts.ACTION_IDLE) {
      // console.log('Ending action: ' + this.action)
      this.action = consts.ACTION_IDLE
      return true
    }

    return false
  }
  doClickUI(e) {
    if (this.UIClickedRect) {
      if (this.UIClickedRect === consts.RECT_BUTTON_FULLSCREEN) {
        if (this.store.getIsFullscreen()) {
          this.store.dispatch('closeFullscreen')
        } else {
          this.store.dispatch('goFullscreen')
        }
      }
      if (this.UIClickedRect === consts.RECT_BUTTON_ZOOM_IN) {
        this.store.dispatch('zoomIn', {})
      }
      if (this.UIClickedRect === consts.RECT_BUTTON_ZOOM_OUT) {
        this.store.dispatch('zoomOut', {})
      }
      if (e.target.classList.contains('imp-clear-search')) {
        this.store.dispatch('clearSearch')
      }
      if (this.UIClickedRect == consts.RECT_OPENED_FULLSCREEN_TOOLTIP) {
        if (
          (e.target.closest('.imp-tooltip-content') === null && !e.target.classList.contains('imp-tooltip-content')) ||
          e.target.closest('.imp-tooltip-close-button') ||
          e.target.classList.contains('imp-tooltip-close-button')
        ) {
          this.store.dispatch('closeFullscreenTooltip')
        } else {
          return false
        }
      }
      if (this.UIClickedRect == consts.RECT_BUTTON_OPEN_MENU) {
        this.store.dispatch('openMenu')
      }
      if (this.UIClickedRect == consts.RECT_BUTTON_CLOSE_MENU) {
        this.store.dispatch('closeMenu')
        this.preventDefault(e)
        return true
      }
      if (this.UIClickedRect == consts.RECT_ARTBOARD_SELECT_MENU) {
        this.store.dispatch('unhighlightAllObjects')
        return false
      }
      if (e.target.closest('.imp-search-box-input-wrap')) {
        return true
      }

      this.store.dispatch('unhighlightAllObjects')
      this.preventDefault(e)
      return true
    }

    return false
  }
  async doClickObject() {
    if (
      this.objectIdClicked !== false &&
      this.getDistanceBetweenCoordinates(this.eventCoordinates, this.eventCoordinatesStart) < 10
    ) {
      await this.store.dispatch('clickObject', { objectId: this.objectIdUnderEvent })

      if (this.store.getImageMap().config.zooming.zoom_on_object_click) {
        await this.store.dispatch('focusObject', { objectId: this.objectIdUnderEvent, showTooltip: false })
      }

      await this.store.dispatch('unhighlightAllObjects')
      this.store.dispatch('highlightObject', {
        objectId: this.objectIdUnderEvent,
        showTooltip: true,
        hideAllTooltips: false,
      })
      return true
    }
    return false
  }
  async doMouseOverObject(e) {
    // Exception when tooltips are sticky
    // Prevent a race condition when the tooltip is limited by screen
    // and gets under the mouse
    if (
      this.store.getTooltipController().stickyTooltips &&
      this.isEventOverTooltip &&
      !this.store.getAreTooltipsFullscreen()
    ) {
      this.store.dispatch('updateTooltipPositions')
      return
    }

    // If sticky tooltips are on, update tooltip position
    if (this.store.getTooltipController().stickyTooltips && !this.store.getAreTooltipsFullscreen()) {
      this.store.dispatch('updateTooltipPositions')
    }

    // If there is a tooltip under the event, return
    if (this.isEventOverTooltip) return false

    // If object under event is the same, return
    if (this.objectIdUnderEventPrevious === this.objectIdUnderEvent) return false

    if (this.objectIdUnderEvent !== false) {
      this.objectIdUnderEventPrevious = this.objectIdUnderEvent
      await this.store.dispatch('unhighlightAllObjects')
      let showTooltip = true
      if (this.store.state.tooltips.show_tooltips == 'click') showTooltip = false
      this.store.dispatch('highlightObject', {
        objectId: this.objectIdUnderEvent,
        showTooltip: showTooltip,
        hideAllTooltips: false,
      })

      return true
    }

    if (this.objectIdUnderEvent === false) {
      this.objectIdUnderEventPrevious = false
      this.store.dispatch('unhighlightAllObjects')
    }

    return false
  }
  doMenuStart(e) {
    if (this.UIRectUnderEvent !== consts.RECT_MENU) return false
  }
  doMenuMove(e) {
    // If the menu list item is the same, return
    if (this.menuListItemIDUnderEventPrevious === this.menuListItemIDUnderEvent) return false

    // If there is a menu list item under event, highlight the object
    if (this.menuListItemIDUnderEvent) {
      if (!isMobile()) {
        this.menuListItemIDUnderEventPrevious = this.menuListItemIDUnderEvent
        this.store.dispatch('unhighlightAllObjects')

        if (!this.store.getObject({ id: this.menuListItemIDUnderEvent }).static) {
          this.store.dispatch('highlightObject', { objectId: this.menuListItemIDUnderEvent, showTooltip: false })
        }

        return true
      }
    }

    if (this.menuListItemIDUnderEvent === false) {
      this.objectIdUnderEventPrevious = null
      this.menuListItemIDUnderEventPrevious = false
      return false
    }

    return false
  }
  async doMenuEnd(e) {
    if (this.getDistanceBetweenCoordinates(this.eventCoordinates, this.eventCoordinatesStart) > 10) return
    if (this.UIRectUnderEvent !== consts.RECT_MENU) return false

    if (
      e.target.classList.contains('imp-object-list-item-artboard') ||
      e.target.closest('.imp-object-list-item-artboard')
    ) {
      this.store.dispatch('toggleArtboard', { artboardId: this.menuListItemIDUnderEvent })
      this.preventDefault(e)
      return true
    }

    if (e.target.classList.contains('imp-object-list-item-group') || e.target.closest('.imp-object-list-item-group')) {
      this.store.dispatch('toggleGroup', { groupId: this.menuListItemIDUnderEvent })
      this.preventDefault(e)
      return true
    }

    if (this.menuListItemIDUnderEvent) {
      if (this.store.getObject({ id: this.menuListItemIDUnderEvent }).actions.click === 'change-artboard') {
        // Exception when the object's action is to change the artboard
        // prevent the double change of artboard
        // zoom out, because clicking an object like this does not focus on it, since the artboard changes
        await this.store.dispatch('changeArtboard', {
          artboardId: this.store.getObject({ id: this.menuListItemIDUnderEvent }).actions.artboard,
          zoomOut: true,
        })
        this.preventDefault(e)
        return true
      } else {
        await this.store.dispatch('changeArtboard', {
          artboardId: this.store.getArtboardIdForObject({ id: this.menuListItemIDUnderEvent }),
          zoomOut: false,
        })
      }

      if (!this.store.getObject({ id: this.menuListItemIDUnderEvent }).static) {
        if (this.store.getImageMap().config.zooming.zoom_on_object_click) {
          await this.store.dispatch('focusObject', { objectId: this.menuListItemIDUnderEvent })
        }
        await this.store.dispatch('highlightObject', {
          objectId: this.menuListItemIDUnderEvent,
          showTooltip: true,
          hideAllTooltips: true,
        })
        await this.store.dispatch('clickObject', { objectId: this.menuListItemIDUnderEvent })
      }

      this.preventDefault(e)
      return true
    }

    return false
  }
  doZoom(e) {
    let shouldAnimate = this.action == consts.ACTION_PAN ? false : true

    if (e.deltaY > 0) {
      this.store.dispatch('zoomOut', { coords: this.eventCoordinates, animate: shouldAnimate })
    } else {
      this.store.dispatch('zoomIn', { coords: this.eventCoordinates, animate: shouldAnimate })
    }

    this.preventDefault(e)

    if (this.action == consts.ACTION_PAN) {
      this.store.dispatch('startPan', this.eventCoordinates)
    }
  }

  // Helpers
  preventDefault(e) {
    if (e.cancelable) e.preventDefault()
  }
  getUIRectNameUnderEvent() {
    let orderedRectNames = [
      consts.RECT_OPENED_FULLSCREEN_TOOLTIP,
      consts.RECT_BUTTON_FULLSCREEN,
      consts.RECT_BUTTON_ZOOM_IN,
      consts.RECT_BUTTON_ZOOM_OUT,
      consts.RECT_NAVIGATOR,
      consts.RECT_ARTBOARD_SELECT_MENU,
      consts.RECT_MENU,
      consts.RECT_BUTTON_OPEN_MENU,
      consts.RECT_BUTTON_CLOSE_MENU,
    ]

    let result = false

    for (let rectName of orderedRectNames) {
      if (this.UIRects[rectName]) {
        if (this.isPointInsideRect(this.eventCoordinates, this.UIRects[rectName]())) {
          this.UIRectUnderEvent = rectName
          result = rectName
        }
      }
    }

    return result
  }
  isPointInsideRect(point, rect) {
    if (!rect) return false

    return (
      point.x > rect.offset.left &&
      point.x < rect.offset.left + rect.offsetWidth &&
      point.y > rect.offset.top &&
      point.y < rect.offset.top + rect.offsetHeight
    )
  }
  getObjectIdUnderEvent(e) {
    // Check if the event target is NOT an object
    let id
    if (e.target.dataset.parentId) id = e.target.dataset.parentId
    else if (e.target.closest('[data-parent-id]')?.dataset.parentId)
      id = e.target.closest('[data-parent-id]')?.dataset.parentId
    else if (e.target.dataset.objectId) id = e.target.dataset.objectId
    else if (e.target.closest('[data-object-id]')?.dataset.objectId)
      id = e.target.closest('[data-object-id]')?.dataset.objectId
    if (!id) return false

    // Check if the event target belongs to another image map
    let targetImageMapId = e.target.dataset.imageMapId || e.target.closest('[data-image-map-id]')?.dataset.imageMapId

    if (targetImageMapId !== undefined && targetImageMapId + '' !== this.store.getID()) return false
    return id
  }
  isEventOverVisibleTooltip(e) {
    if (e.target.classList.contains('imp-tooltip') || e.target.closest('.imp-tooltip')) return true
  }
  getMenuListItemIdUnderEvent(e) {
    // Check if the event target is NOT a menu list item
    const listItemId = e.target.dataset.listItemId || e.target.closest('[data-list-item-id]')?.dataset.listItemId
    if (!listItemId) return false

    // Check if the object belongs to this image map
    const imageMapId = e.target.dataset.imageMapId || e.target.closest('[data-list-item-id]')?.dataset.imageMapId
    if (imageMapId !== this.store.getID()) return false

    return e.target.dataset.listItemId || e.target.closest('[data-list-item-id]')?.dataset.listItemId
  }
  getDistanceBetweenCoordinates(coord1, coord2) {
    return Math.sqrt(Math.pow(coord2.x - coord1.x, 2) + Math.pow(coord2.y - coord1.y, 2))
  }
  getZoomedCanvasRect() {
    if (this.store.getIsFullscreen()) {
      let objectMenuWidth = 0
      if (this.store.state.object_list.enable_object_list && !this.store.getIsMenuMobile()) {
        objectMenuWidth = 224
      }
      return {
        offset: {
          left: 0,
          top: window.scrollY,
        },
        offsetWidth: window.innerWidth - objectMenuWidth,
        offsetHeight: window.innerHeight,
      }
    } else {
      return this.store.getCanvasWrapRect()
    }
  }
  getCanPinch(e) {
    if (
      e.touches?.length == 2 &&
      this.isPointInsideRect({ x: e.touches[0].pageX, y: e.touches[0].pageY }, this.getZoomedCanvasRect()) &&
      this.isPointInsideRect({ x: e.touches[1].pageX, y: e.touches[1].pageY }, this.getZoomedCanvasRect())
    ) {
      return true
    } else {
      return false
    }
  }
  isPanLimitReached() {
    if (
      (this.eventDirection == consts.MOUSE_DIRECTION_UP && this.store.getPan().y > this.store.getMinPan().y) ||
      (this.eventDirection == consts.MOUSE_DIRECTION_DOWN && this.store.getPan().y < 0) ||
      (this.eventDirection == consts.MOUSE_DIRECTION_LEFT && this.store.getPan().x > this.store.getMinPan().y) ||
      (this.eventDirection == consts.MOUSE_DIRECTION_RIGHT && this.store.getPan().x < 0)
    ) {
      return false
    }

    return true
  }
  updateStickyTooltipsConfig() {
    if (this.UIRectUnderEvent === consts.RECT_MENU) {
      this.store.getTooltipController().disableStickyTooltips()
    } else {
      this.store.getTooltipController().resetStickyTooltips()
    }
  }
}