{"version":3,"file":"CanvasEventHandler.mjs","sources":["../../../../../packages/sdk/plugins/CanvasEventHandler.ts"],"sourcesContent":["interface RelativeCanvasCoords {\n  x: number\n  y: number\n}\n\ntype EventHandlerCallback<T extends Event> = (\n  eventType: T,\n  canvasCoords?: RelativeCanvasCoords,\n  event?: MouseEvent | TouchEvent | KeyboardEvent\n) => void\n\ninterface CustomEventHandlers {\n  mousedown?: EventHandlerCallback<MouseEvent>\n  mouseup?: EventHandlerCallback<MouseEvent>\n  mousemove?: EventHandlerCallback<MouseEvent>\n  touchstart?: EventHandlerCallback<TouchEvent>\n  touchmove?: EventHandlerCallback<TouchEvent>\n  touchend?: EventHandlerCallback<TouchEvent>\n  keydown?: EventHandlerCallback<KeyboardEvent>\n  keyup?: EventHandlerCallback<KeyboardEvent>\n}\n\nexport class CanvasEventHandler {\n  private canvas: HTMLCanvasElement\n  // @ts-ignore: TS6133\n  private context: CanvasRenderingContext2D | null\n  private eventHandlers: CustomEventHandlers = {}\n  private onInteraction: any\n\n  /**\n   * 构造函数，初始化 Canvas 及其上下文，设置默认事件处理器\n   * @param {HTMLCanvasElement} canvas - 要处理事件的 Canvas 元素\n   * @param {CustomEventHandlers} [eventHandlers] - 自定义事件处理器对象（可选）\n   */\n  constructor(\n    canvas: HTMLCanvasElement,\n    eventHandlers: CustomEventHandlers = {}\n  ) {\n    this.canvas = canvas\n    this.context = canvas.getContext('2d')\n\n    // 用户自定义事件处理器，优先级高于默认处理器\n    this.eventHandlers = {\n      ...this.defaultEventHandlers,\n      ...eventHandlers,\n    }\n    // 添加事件监听器\n    this.addEventListeners()\n  }\n\n  private defaultEventHandlers: CustomEventHandlers = {\n    mousedown: this.handleMouseDown.bind(this),\n    mouseup: this.handleMouseUp.bind(this),\n    mousemove: this.handleMouseMove.bind(this),\n    touchstart: this.handleTouchStart.bind(this),\n    touchmove: this.handleTouchMove.bind(this),\n    touchend: this.handleTouchEnd.bind(this),\n    keydown: this.handleKeyDown.bind(this),\n    keyup: this.handleKeyUp.bind(this),\n  }\n\n  /**\n   * 添加事件监听器到 Canvas 元素\n   */\n  addEventListeners(): void {\n    const events = Object.keys(this.eventHandlers)\n    events.forEach((eventType) => {\n      this.canvas.addEventListener(\n        eventType,\n        (this.eventHandlers as any)[eventType]\n      )\n    })\n  }\n\n  /**\n   * 移除所有已添加的事件监听器\n   */\n  removeEventListeners(): void {\n    const events = Object.keys(this.eventHandlers || {})\n    events.forEach((eventType) => {\n      this.canvas.removeEventListener(\n        eventType,\n        (this.eventHandlers as any)[eventType]\n      )\n    })\n  }\n\n  /**\n   * 获取相对于 Canvas 的坐标\n   * @param {Event} event - 浏览器事件对象\n   * @returns {RelativeCanvasCoords} - 包含 x 和 y 属性的对象，表示相对 Canvas 的坐标\n   */\n  getRelativeCanvasCoords(\n    event: MouseEvent | TouchEvent\n  ): RelativeCanvasCoords {\n    const rect = this.canvas.getBoundingClientRect()\n    return {\n      x: (event as MouseEvent).clientX - rect.left,\n      y: (event as MouseEvent).clientY - rect.top,\n    }\n  }\n\n  /**\n   * 处理鼠标按下事件\n   * @param {MouseEvent} event - 鼠标按下事件对象\n   */\n  handleMouseDown(event: MouseEvent): void {\n    const canvasCoords = this.getRelativeCanvasCoords(event)\n    this.handleInteraction('mousedown', canvasCoords, event)\n  }\n\n  /**\n   * 处理鼠标抬起事件\n   * @param {MouseEvent} event - 鼠标抬起事件对象\n   */\n  handleMouseUp(event: MouseEvent): void {\n    const canvasCoords = this.getRelativeCanvasCoords(event)\n    this.handleInteraction('mouseup', canvasCoords, event)\n  }\n  // @ts-ignore: TS6133\n  private isNearPoint(\n    event: RelativeCanvasCoords,\n    point: { x: number; y: number },\n    threshold = 10\n  ) {\n    const { x, y } = point\n    if (x && y) {\n      const dx = Math.abs(event.x - x)\n      const dy = Math.abs(event.y - y)\n      return dx <= threshold && dy <= threshold\n    }\n    return false\n  }\n\n  /**\n   * 处理鼠标移动事件\n   * @param {MouseEvent} event - 鼠标移动事件对象\n   */\n  handleMouseMove(event: MouseEvent): void {\n    const canvasCoords = this.getRelativeCanvasCoords(event)\n    // const isMouseInInteractiveArea = this.isNearPoint(canvasCoords) // 实现此方法以判断鼠标是否位于可操作区域\n\n    // if (isMouseInInteractiveArea) {\n    //   this.canvas.classList.add('interactive-cursor')\n    // } else {\n    //   this.canvas.classList.remove('interactive-cursor')\n    // }\n    this.handleInteraction('mousemove', canvasCoords, event)\n  }\n\n  /**\n   * 处理触摸开始事件\n   * @param {TouchEvent} event - 触摸开始事件对象\n   */\n  handleTouchStart(event: TouchEvent): void {\n    event.preventDefault() // 防止浏览器默认行为（如滚动）\n    // const touch = event.changedTouches[0]\n    const canvasCoords = this.getRelativeCanvasCoords(event)\n    this.handleInteraction('touchstart', canvasCoords, event)\n  }\n\n  /**\n   * 处理触摸移动事件\n   * @param {TouchEvent} event - 触摸移动事件对象\n   */\n  handleTouchMove(event: TouchEvent): void {\n    event.preventDefault()\n    // const touch = event.changedTouches[0]\n    const canvasCoords = this.getRelativeCanvasCoords(event)\n    this.handleInteraction('touchmove', canvasCoords, event)\n  }\n\n  /**\n   * 处理触摸结束事件\n   * @param {TouchEvent} event - 触摸结束事件对象\n   */\n  handleTouchEnd(event: TouchEvent): void {\n    event.preventDefault()\n    // const touch = event.changedTouches[0]\n    const canvasCoords = this.getRelativeCanvasCoords(event)\n    this.handleInteraction('touchend', canvasCoords, event)\n  }\n\n  /**\n   * 处理键盘按下事件\n   * @param {KeyboardEvent} event - 键盘按下事件对象\n   */\n  handleKeyDown(event: KeyboardEvent): void {\n    this.handleInteraction('keydown', null, event)\n  }\n\n  /**\n   * 处理键盘抬起事件\n   * @param {KeyboardEvent} event - 键盘抬起事件对象\n   */\n  handleKeyUp(event: KeyboardEvent): void {\n    this.handleInteraction('keyup', null, event)\n  }\n\n  /**\n   * 基于回调函数处理交互事件\n   * @param {string} eventType - 事件类型（如 'mousedown', 'mousemove' 等）\n   * @param {RelativeCanvasCoords} [canvasCoords] - 相对于 Canvas 的坐标（仅适用于鼠标和触摸事件）\n   * @param {Event} [event] - 原始浏览器事件对象\n   */\n  handleInteraction(\n    eventType: string,\n    canvasCoords?: RelativeCanvasCoords | null,\n    event?: Event\n  ): void {\n    // 这里可以定义或调用应用特定的事件处理逻辑\n    // 您可以提供一个外部接口（如 `onInteraction`），供用户自定义事件处理函数\n    // 示例：\n    if (this.onInteraction) {\n      this.onInteraction(eventType, canvasCoords, event)\n    }\n  }\n}\n// const canvas = document.getElementById('myCanvas')\n// const handler = new CanvasEventHandler(canvas, {\n//   mousedown: customMouseDownHandler,\n//   keydown: customKeyDownHandler\n// })\n\n// function customMouseDownHandler(eventType, canvasCoords, event) {\n//   console.log('Custom mousedown handler:', canvasCoords)\n// }\n\n// function customKeyDownHandler(eventType, canvasCoords, event) {\n//   console.log('Custom keydown handler:', event.key)\n// }\n"],"names":["CanvasEventHandler","constructor","e","n","this","eventHandlers","defaultEventHandlers","mousedown","handleMouseDown","bind","mouseup","handleMouseUp","mousemove","handleMouseMove","touchstart","handleTouchStart","touchmove","handleTouchMove","touchend","handleTouchEnd","keydown","handleKeyDown","keyup","handleKeyUp","canvas","context","getContext","addEventListeners","Object","keys","forEach","addEventListener","removeEventListeners","removeEventListener","getRelativeCanvasCoords","getBoundingClientRect","x","clientX","left","y","clientY","top","handleInteraction","isNearPoint","t","a","s","o","Math","abs","v","preventDefault","onInteraction"],"mappings":"AAAO,MAAMA,EAAmB,WAAAC,CAAYC,EAAEC,EAAE,CAAE,GAAEC,KAAKC,cAAc,CAAE,EAACD,KAAKE,qBAAqB,CAACC,UAAUH,KAAKI,gBAAgBC,KAAKL,MAAMM,QAAQN,KAAKO,cAAcF,KAAKL,MAAMQ,UAAUR,KAAKS,gBAAgBJ,KAAKL,MAAMU,WAAWV,KAAKW,iBAAiBN,KAAKL,MAAMY,UAAUZ,KAAKa,gBAAgBR,KAAKL,MAAMc,SAASd,KAAKe,eAAeV,KAAKL,MAAMgB,QAAQhB,KAAKiB,cAAcZ,KAAKL,MAAMkB,MAAMlB,KAAKmB,YAAYd,KAAKL,OAAOA,KAAKoB,OAAOtB,EAAEE,KAAKqB,QAAQvB,EAAEwB,WAAW,MAAMtB,KAAKC,cAAc,IAAID,KAAKE,wBAAwBH,GAAGC,KAAKuB,mBAAmB,CAAC,iBAAAA,GAAoBC,OAAOC,KAAKzB,KAAKC,eAAeyB,SAAQ3B,IAAIC,KAAKoB,OAAOO,iBAAiB5B,EAAEC,KAAKC,cAAcF,MAAK,CAAC,oBAAA6B,GAAuBJ,OAAOC,KAAKzB,KAAKC,eAAe,CAAA,GAAIyB,SAAQ3B,IAAIC,KAAKoB,OAAOS,oBAAoB9B,EAAEC,KAAKC,cAAcF,MAAK,CAAC,uBAAA+B,CAAwBhC,GAAG,MAAMC,EAAEC,KAAKoB,OAAOW,wBAAwB,MAAM,CAACC,EAAElC,EAAEmC,QAAQlC,EAAEmC,KAAKC,EAAErC,EAAEsC,QAAQrC,EAAEsC,IAAI,CAAC,eAAAjC,CAAgBN,GAAG,MAAMC,EAAEC,KAAK8B,wBAAwBhC,GAAGE,KAAKsC,kBAAkB,YAAYvC,EAAED,EAAE,CAAC,aAAAS,CAAcT,GAAG,MAAMC,EAAEC,KAAK8B,wBAAwBhC,GAAGE,KAAKsC,kBAAkB,UAAUvC,EAAED,EAAE,CAAC,WAAAyC,CAAYzC,EAAEC,EAAEyC,EAAE,IAAI,MAAMR,EAAES,EAAEN,EAAEO,GAAG3C,EAAE,GAAG0C,GAAGC,EAAE,CAAC,MAAMC,EAAEC,KAAKC,IAAI/C,EAAEkC,EAAES,GAAGK,EAAEF,KAAKC,IAAI/C,EAAEqC,EAAEO,GAAG,OAAOC,GAAGH,GAAGM,GAAGN,CAAC,CAAC,OAAM,CAAE,CAAC,eAAA/B,CAAgBX,GAAG,MAAMC,EAAEC,KAAK8B,wBAAwBhC,GAAGE,KAAKsC,kBAAkB,YAAYvC,EAAED,EAAE,CAAC,gBAAAa,CAAiBb,GAAGA,EAAEiD,iBAAiB,MAAMhD,EAAEC,KAAK8B,wBAAwBhC,GAAGE,KAAKsC,kBAAkB,aAAavC,EAAED,EAAE,CAAC,eAAAe,CAAgBf,GAAGA,EAAEiD,iBAAiB,MAAMhD,EAAEC,KAAK8B,wBAAwBhC,GAAGE,KAAKsC,kBAAkB,YAAYvC,EAAED,EAAE,CAAC,cAAAiB,CAAejB,GAAGA,EAAEiD,iBAAiB,MAAMhD,EAAEC,KAAK8B,wBAAwBhC,GAAGE,KAAKsC,kBAAkB,WAAWvC,EAAED,EAAE,CAAC,aAAAmB,CAAcnB,GAAGE,KAAKsC,kBAAkB,UAAU,KAAKxC,EAAE,CAAC,WAAAqB,CAAYrB,GAAGE,KAAKsC,kBAAkB,QAAQ,KAAKxC,EAAE,CAAC,iBAAAwC,CAAkBxC,EAAEC,EAAEyC,GAAGxC,KAAKgD,eAAehD,KAAKgD,cAAclD,EAAEC,EAAEyC,EAAE"}