diff --git a/common/changes/@visactor/vtable/3734-refactor-unify-event-listen-use-vrender_2025-04-15-09-07.json b/common/changes/@visactor/vtable/3734-refactor-unify-event-listen-use-vrender_2025-04-15-09-07.json new file mode 100644 index 0000000000..a29918cc3a --- /dev/null +++ b/common/changes/@visactor/vtable/3734-refactor-unify-event-listen-use-vrender_2025-04-15-09-07.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "refactor: change event listener with vglobal #3734\n\n", + "type": "none", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "892739385@qq.com" +} \ No newline at end of file diff --git a/packages/vtable-editors/src/list-editor.ts b/packages/vtable-editors/src/list-editor.ts index 8dcebee035..359caff6b8 100644 --- a/packages/vtable-editors/src/list-editor.ts +++ b/packages/vtable-editors/src/list-editor.ts @@ -37,8 +37,6 @@ export class ListEditor implements IEditor { // input.style.boxShadow = 'none'; }); - - this.element = select; // create option tags @@ -86,7 +84,6 @@ export class ListEditor implements IEditor { } adjustPosition(rect: RectProps) { - //使border均分input位置rect的上下左右 const borderWidth = 2; const top = rect.top - borderWidth / 2; @@ -94,8 +91,8 @@ export class ListEditor implements IEditor { const width = rect.width + borderWidth; const height = rect.height + borderWidth; - this.element.style.top =top + 'px'; - this.element.style.left =left + 'px'; + this.element.style.top = top + 'px'; + this.element.style.left = left + 'px'; this.element.style.width = width + 'px'; this.element.style.height = height + 'px'; } diff --git a/packages/vtable-editors/src/textArea-editor.ts b/packages/vtable-editors/src/textArea-editor.ts index 1f575c9083..53cd9ee6ce 100644 --- a/packages/vtable-editors/src/textArea-editor.ts +++ b/packages/vtable-editors/src/textArea-editor.ts @@ -83,8 +83,6 @@ export class TextAreaEditor implements IEditor { } adjustPosition(rect: RectProps) { - - //使border均分input位置rect的上下左右 const borderWidth = 2; const top = rect.top - borderWidth / 2; diff --git a/packages/vtable-plugins/demo/menu.ts b/packages/vtable-plugins/demo/menu.ts index d6b5778cf2..6f09d55fca 100644 --- a/packages/vtable-plugins/demo/menu.ts +++ b/packages/vtable-plugins/demo/menu.ts @@ -35,6 +35,10 @@ export const menus = [ path: 'combine-plugins', name: 'combine-plugins' }, + { + path: 'rotate-table', + name: 'rotate-table' + }, { menu: 'pivot-plugin', children: [ diff --git a/packages/vtable-plugins/demo/rotate-table/rotate-table.ts b/packages/vtable-plugins/demo/rotate-table/rotate-table.ts new file mode 100644 index 0000000000..93ae773f8f --- /dev/null +++ b/packages/vtable-plugins/demo/rotate-table/rotate-table.ts @@ -0,0 +1,162 @@ +import * as VTable from '@visactor/vtable'; +import { bindDebugTool } from '@visactor/vtable/es/scenegraph/debug-tool'; +import * as VTable_editors from '@visactor/vtable-editors'; + +import { RotateTablePlugin } from '../../src'; +const CONTAINER_ID = 'vTable'; +const generatePersons = count => { + return Array.from(new Array(count)).map((_, i) => ({ + id: i + 1, + email1: `${i + 1}@xxx.com`, + name: `小明${i + 1}`, + lastName: '王', + date1: '2022年9月1日', + tel: '000-0000-0000', + sex: i % 2 === 0 ? 'boy' : 'girl', + work: i % 2 === 0 ? 'back-end engineer' + (i + 1) : 'front-end engineer' + (i + 1), + city: 'beijing', + image: + '' + })); +}; + +export function createTable() { + const input_editor = new VTable_editors.InputEditor(); + VTable.register.editor('input-editor', input_editor); + + const records = generatePersons(40); + const columns: VTable.ColumnsDefine = [ + { + field: 'id', + title: 'ID', + width: 'auto', + minWidth: 50, + sort: true, + headerEditor: 'input-editor', + editor: 'input-editor' + }, + { + field: 'email1', + title: 'email', + width: 200, + sort: true, + style: { + underline: true, + underlineDash: [2, 0], + underlineOffset: 3 + } + }, + { + field: 'date1', + title: 'birthday', + width: 200 + }, + { + field: 'sex', + title: 'sex', + width: 100 + }, + { + field: 'id', + title: 'ID', + width: 'auto', + minWidth: 50, + sort: true, + headerEditor: 'input-editor', + editor: 'input-editor' + }, + { + field: 'email1', + title: 'email', + width: 200, + sort: true, + style: { + underline: true, + underlineDash: [2, 0], + underlineOffset: 3 + } + }, + { + field: 'date1', + title: 'birthday', + width: 200 + }, + { + field: 'sex', + title: 'sex', + width: 100 + }, + { + field: 'id', + title: 'ID', + width: 'auto', + minWidth: 50, + sort: true, + headerEditor: 'input-editor', + editor: 'input-editor' + }, + { + field: 'email1', + title: 'email', + width: 200, + sort: true, + style: { + underline: true, + underlineDash: [2, 0], + underlineOffset: 3 + } + }, + { + field: 'date1', + title: 'birthday', + width: 200 + }, + { + field: 'sex', + title: 'sex', + width: 100 + } + ]; + + const rotatePlugin = new RotateTablePlugin(); + const option: VTable.ListTableConstructorOptions = { + records, + columns, + rowSeriesNumber: {}, + select: { + outsideClickDeselect: true, + headerSelectMode: 'body' + }, + autoWrapText: true, + editor: 'input-editor', + overscrollBehavior: 'none', + menu: { + contextMenuItems: ['copy', 'paste', 'delete', '...'] + }, + plugins: [rotatePlugin] + }; + const tableInstance = new VTable.ListTable(document.getElementById(CONTAINER_ID)!, option); + window.tableInstance = tableInstance; + window.transform = function () { + const bigContainer: HTMLElement = document.getElementsByClassName('container')[0] as HTMLElement; + const bigContainerWidth = bigContainer.clientWidth; + const bigContainerHeight = bigContainer.clientHeight; + bigContainer.style.width = `${bigContainerHeight}px`; + bigContainer.style.height = `${bigContainerWidth}px`; + tableInstance.rotate90WithTransform(bigContainer); + }; + window.cancelTransform = function () { + const bigContainer: HTMLElement = document.getElementsByClassName('container')[0] as HTMLElement; + + const bigContainerWidth = bigContainer.clientWidth; + const bigContainerHeight = bigContainer.clientHeight; + bigContainer.style.width = `${bigContainerHeight}px`; + bigContainer.style.height = `${bigContainerWidth}px`; + tableInstance.cancelTransform(bigContainer); + }; + bindDebugTool(tableInstance.scenegraph.stage, { + customGrapicKeys: ['col', 'row'] + }); + + // tableInstance.scenegraph.temporarilyUpdateSelectRectStyle({stroke: false}) +} diff --git a/packages/vtable-plugins/src/excel-edit-cell-keyboard.ts b/packages/vtable-plugins/src/excel-edit-cell-keyboard.ts index c835ce9c77..32394cfcbc 100644 --- a/packages/vtable-plugins/src/excel-edit-cell-keyboard.ts +++ b/packages/vtable-plugins/src/excel-edit-cell-keyboard.ts @@ -1,5 +1,3 @@ -import type { CellRange } from '@visactor/vtable/es/ts-types'; -import type { BaseTableAPI } from '@visactor/vtable/es/ts-types/base-table'; import * as VTable from '@visactor/vtable'; import type { TableEvents } from '@visactor/vtable/src/core/TABLE_EVENT_TYPE'; import type { EventArg } from './types'; diff --git a/packages/vtable-plugins/src/index.ts b/packages/vtable-plugins/src/index.ts index 90b20be375..b21daf8a36 100644 --- a/packages/vtable-plugins/src/index.ts +++ b/packages/vtable-plugins/src/index.ts @@ -9,3 +9,4 @@ export * from './excel-edit-cell-keyboard'; export * from './types'; export * from './focus-highlight'; export * from './table-carousel-animation'; +export * from './rotate-table'; diff --git a/packages/vtable-plugins/src/rotate-table.ts b/packages/vtable-plugins/src/rotate-table.ts new file mode 100644 index 0000000000..7ab8b1ad17 --- /dev/null +++ b/packages/vtable-plugins/src/rotate-table.ts @@ -0,0 +1,121 @@ +import { + matrixAllocate, + transformPointForCanvas, + mapToCanvasPointForCanvas, + registerGlobalEventTransformer, + registerWindowEventTransformer, + vglobal +} from '@visactor/vtable/es/vrender'; +import type { BaseTable } from '@visactor/vtable/src/core/BaseTable'; +import * as VTable from '@visactor/vtable'; +import type { TableEvents } from '@visactor/vtable/src/core/TABLE_EVENT_TYPE'; +import type { EventArg } from './types'; +// export type IRotateTablePluginOptions = { +// // 旋转角度 +// rotate?: number; +// }; +/** + * 旋转表格插件。 + * 业务层旋转功能没有使用收系统接口的话,用的transform:'rotate(90deg)'的设置来达到旋转的目的。vtable及vrender都没有进行坐标处理,这样就会导致交互错乱。 + * 所以需要进行坐标转换,将旋转后的坐标转换后作为VRender及VTable逻辑中用到的坐标。 + * 这里使用transform:'rotate(90deg)'的设置来达到旋转的目的。 其他角度应该也是可以实现的,请自行扩展这个插件并兼容 + */ +export class RotateTablePlugin implements VTable.plugins.IVTablePlugin { + id = 'rotate-table'; + runTime = [VTable.TABLE_EVENT_TYPE.INITIALIZED]; + table: VTable.ListTable; + // pluginOptions: IRotateTablePluginOptions; + constructor() { + // this.pluginOptions = pluginOptions; + } + run(...args: [EventArg, TableEvents[keyof TableEvents] | TableEvents[keyof TableEvents][], VTable.BaseTableAPI]) { + const table: VTable.BaseTableAPI = args[2]; + this.table = table as VTable.ListTable; + //将函数rotate90WithTransform绑定到table实例上 + this.table.rotate90WithTransform = rotate90WithTransform.bind(this.table); + this.table.cancelTransform = cancelTransform.bind(this.table); + } + + release() { + // 移除绑定的事件 + } +} + +/** + * 业务层旋转功能没有使用收系统接口的话,用的transform:'rotate(90deg)'的设置来达到旋转的目的。vtable及vrender都没有进行坐标处理,这样就会导致交互错乱。 + * 所以需要进行坐标转换,将旋转后的坐标转换后作为VRender及VTable逻辑中用到的坐标。 + */ +export function rotate90WithTransform(this: BaseTable, rotateDom: HTMLElement) { + const rotateCenter = Math.min(rotateDom.clientWidth, rotateDom.clientHeight) / 2; + const domRect = this.getElement().getBoundingClientRect(); + const x1 = domRect.left; + const y1 = domRect.top; + const x2 = domRect.right; + const y2 = domRect.bottom; + rotateDom.style.transform = 'rotate(90deg)'; + rotateDom.style.transformOrigin = `${rotateCenter}px ${rotateCenter}px`; + + const getRect = () => { + return { + x1, + y1, + x2, + y2 + }; + }; + const getMatrix = () => { + const matrix = matrixAllocate.allocate(1, 0, 0, 1, 0, 0); + matrix.translate(x1, y1); + const centerX = rotateCenter - x1; + const centerY = rotateCenter - y1; + matrix.translate(centerX, centerY); + matrix.rotate(Math.PI / 2); + matrix.translate(-centerX, -centerY); + return matrix; + }; + registerGlobalEventTransformer(vglobal, this.getElement(), getMatrix, getRect, transformPointForCanvas); + registerWindowEventTransformer( + this.scenegraph.stage.window, + this.getElement(), + getMatrix, + getRect, + transformPointForCanvas + ); + vglobal.mapToCanvasPoint = mapToCanvasPointForCanvas; + //transformPointForCanvas和mapToCanvasPointForCanvas时相对应的 + //具体逻辑在 VRender/packages/vrender-core/src/common/event-transformer.ts中 + // 可以自定义这两个函数 来修改事件属性,transformPointForCanvas中将坐标转换后存放了_canvasX _canvasY,mapToCanvasPointForCanvas中加以利用 + // 在VTable的touch文件中,利用到了_canvasX _canvasY 所以如果自定义上面两个函数也需提供_canvasX _canvasY +} +export function cancelTransform(this: BaseTable, rotateDom: HTMLElement) { + rotateDom.style.transform = 'none'; + rotateDom.style.transformOrigin = 'none'; + const domRect = this.getElement().getBoundingClientRect(); + const x1 = domRect.left; + const y1 = domRect.top; + const x2 = domRect.right; + const y2 = domRect.bottom; + + const getRect = () => { + return { + x1, + y1, + x2, + y2 + }; + }; + const getMatrix = () => { + const matrix = matrixAllocate.allocate(1, 0, 0, 1, 0, 0); + matrix.translate(x1, y1); + return matrix; + }; + registerGlobalEventTransformer(vglobal, this.getElement(), getMatrix, getRect, transformPointForCanvas); + registerWindowEventTransformer( + this.scenegraph.stage.window, + this.getElement(), + getMatrix, + getRect, + transformPointForCanvas + ); + vglobal.mapToCanvasPoint = mapToCanvasPointForCanvas; +} diff --git a/packages/vtable/package.json b/packages/vtable/package.json index a10b048d21..683c8e0660 100644 --- a/packages/vtable/package.json +++ b/packages/vtable/package.json @@ -129,4 +129,4 @@ "url": "https://github.com/VisActor/VTable.git", "directory": "packages/vtable" } -} +} \ No newline at end of file diff --git a/packages/vtable/src/event/event.ts b/packages/vtable/src/event/event.ts index 3a6f4126b8..6965ad8416 100644 --- a/packages/vtable/src/event/event.ts +++ b/packages/vtable/src/event/event.ts @@ -1,6 +1,6 @@ // import { FederatedPointerEvent } from '@src/vrender'; import type { FederatedPointerEvent, Gesture, IEventTarget } from '@src/vrender'; -import { RichText } from '@src/vrender'; +import { RichText, vglobal } from '@src/vrender'; import type { ColumnDefine, ListTableConstructorOptions, MousePointerCellEvent } from '../ts-types'; import { IconFuncTypeEnum } from '../ts-types'; import type { StateManager } from '../state/state'; @@ -60,7 +60,11 @@ export class EventManager { scrollXSpeed: number; downIcon: IEventTarget; // 记录鼠标按下的sicon //报错已绑定过的事件 后续清除绑定 - globalEventListeners: { name: string; env: 'document' | 'body' | 'window'; callback: (e?: any) => void }[] = []; + globalEventListeners: { + name: string; + env: 'document' | 'body' | 'window' | 'vglobal'; + callback: (e?: any) => void; + }[] = []; inertiaScroll: InertiaScroll; bindSparklineHoverEvent: boolean; @@ -705,6 +709,8 @@ export class EventManager { document.body.removeEventListener(item.name, item.callback); } else if (item.env === 'window') { window.removeEventListener(item.name, item.callback); + } else if (item.env === 'vglobal') { + vglobal.removeEventListener(item.name, item.callback); } }); this.globalEventListeners = []; diff --git a/packages/vtable/src/event/listener/container-dom.ts b/packages/vtable/src/event/listener/container-dom.ts index 4a5fbe571b..40c868f6c4 100644 --- a/packages/vtable/src/event/listener/container-dom.ts +++ b/packages/vtable/src/event/listener/container-dom.ts @@ -4,12 +4,13 @@ import type { ListTableConstructorOptions, MousePointerMultiCellEvent } from '.. import { InteractionState, type KeydownEvent, type ListTableAPI } from '../../ts-types'; import { TABLE_EVENT_TYPE } from '../../core/TABLE_EVENT_TYPE'; import { handleWhell } from '../scroll'; -import { browser } from '../../tools/helper'; +import { browser, getPromiseValue } from '../../tools/helper'; import type { EventManager } from '../event'; import { getPixelRatio } from '../../tools/pixel-ratio'; import { endResizeCol, endResizeRow } from './table-group'; import { isCellDisableSelect } from '../../state/select/is-cell-select-highlight'; import { fireMoveColEventListeners } from '../helper'; +import { vglobal } from '@src/vrender'; export function bindContainerDomListener(eventManager: EventManager) { const table = eventManager.table; const stateManager = table.stateManager; @@ -566,13 +567,31 @@ export function bindContainerDomListener(eventManager: EventManager) { // console.log('body pointerdown'); table.eventManager.LastBodyPointerXY = { x: e.x, y: e.y }; table.eventManager.isDown = true; + + const target = e.target as HTMLElement; + if (!table.getElement().contains(target) && !table.internalProps.menuHandler.containElement(target)) { + // 如果点击到表格外部的dom + const isCompleteEdit = (table as ListTableAPI).editorManager?.completeEdit(e); + getPromiseValue(isCompleteEdit, isCompleteEdit => { + if (isCompleteEdit === false) { + // 如果没有正常退出编辑状态 则不执行下面的逻辑 如选择其他单元格的逻辑 + return; + } + //点击到表格外部不需要取消选中状态 + if (table.options.select?.outsideClickDeselect) { + const isHasSelected = !!stateManager.select.ranges?.length; + eventManager.dealTableSelect(); + stateManager.endSelectCells(true, isHasSelected); + } + }); + } }; eventManager.globalEventListeners.push({ name: 'pointerdown', - env: 'body', + env: 'vglobal', callback: globalPointerdownCallback }); - document.body.addEventListener('pointerdown', globalPointerdownCallback); + vglobal.addEventListener('pointerdown', globalPointerdownCallback); const globalPointerupOutsideCallback = (e: MouseEvent) => { // console.log('pointerupoutside'); @@ -616,9 +635,11 @@ export function bindContainerDomListener(eventManager: EventManager) { const globalPointerupCallback = (e: MouseEvent) => { const target = e.target as HTMLElement; + if (target !== table.canvas) { globalPointerupOutsideCallback(e); } + table.eventManager.LastBodyPointerXY = null; // console.log('body pointerup', table.eventManager.isDown, table.eventManager.isDraging); table.eventManager.isDown = false; @@ -631,14 +652,27 @@ export function bindContainerDomListener(eventManager: EventManager) { } else if (stateManager.isMoveCol()) { const endMoveColSuccess = table.stateManager.endMoveCol(); fireMoveColEventListeners(table, endMoveColSuccess, e); + } else if (table.editorManager.editingEditor) { + if (!table.getElement().contains(target)) { + // 如果点击到表格外部的dom + const isCompleteEdit = (table as ListTableAPI).editorManager?.completeEdit(e); + getPromiseValue(isCompleteEdit, (isCompleteEdit: boolean) => { + if (isCompleteEdit === false) { + // 如果没有正常退出编辑状态 则不执行下面的逻辑 如选择其他单元格的逻辑 + return; + } + stateManager.updateInteractionState(InteractionState.default); + eventManager.dealTableHover(); + }); + } } }; eventManager.globalEventListeners.push({ name: 'pointerup', - env: 'document', + env: 'vglobal', callback: globalPointerupCallback }); - document.addEventListener('pointerup', globalPointerupCallback); + vglobal.addEventListener('pointerup', globalPointerupCallback); const globalPointermoveCallback = (e: MouseEvent) => { if (table.eventManager.isDown && table.eventManager.LastBodyPointerXY) { @@ -807,8 +841,8 @@ export function bindContainerDomListener(eventManager: EventManager) { }; eventManager.globalEventListeners.push({ name: 'pointermove', - env: 'body', + env: 'vglobal', callback: globalPointermoveCallback }); - document.body.addEventListener('pointermove', globalPointermoveCallback); + vglobal.addEventListener('pointermove', globalPointermoveCallback); } diff --git a/packages/vtable/src/event/listener/table-group.ts b/packages/vtable/src/event/listener/table-group.ts index 98bb271688..d794438ac0 100644 --- a/packages/vtable/src/event/listener/table-group.ts +++ b/packages/vtable/src/event/listener/table-group.ts @@ -1,5 +1,5 @@ import type { IEventTarget, FederatedPointerEvent, FederatedWheelEvent, Switch } from '@src/vrender'; -import { Gesture, vglobal } from '@src/vrender'; +import { Gesture } from '@src/vrender'; import type { ListTableAPI, MousePointerCellEvent, @@ -389,55 +389,6 @@ export function bindTableGroupListener(eventManager: EventManager) { // } // }); - const globalPointerupCallback = (e: MouseEvent) => { - const target = e.target as HTMLElement; - if (!table.getElement().contains(target)) { - // 如果点击到表格外部的dom - const isCompleteEdit = (table as ListTableAPI).editorManager?.completeEdit(e); - getPromiseValue(isCompleteEdit, isCompleteEdit => { - if (isCompleteEdit === false) { - // 如果没有正常退出编辑状态 则不执行下面的逻辑 如选择其他单元格的逻辑 - return; - } - stateManager.updateInteractionState(InteractionState.default); - eventManager.dealTableHover(); - }); - } - }; - const globalPointerdownCallback = (e: MouseEvent) => { - const target = e.target as HTMLElement; - if (!table.getElement().contains(target) && !table.internalProps.menuHandler.containElement(target)) { - // 如果点击到表格外部的dom - const isCompleteEdit = (table as ListTableAPI).editorManager?.completeEdit(e); - getPromiseValue(isCompleteEdit, isCompleteEdit => { - if (isCompleteEdit === false) { - // 如果没有正常退出编辑状态 则不执行下面的逻辑 如选择其他单元格的逻辑 - return; - } - //点击到表格外部不需要取消选中状态 - if (table.options.select?.outsideClickDeselect) { - const isHasSelected = !!stateManager.select.ranges?.length; - eventManager.dealTableSelect(); - stateManager.endSelectCells(true, isHasSelected); - } - }); - } - }; - //释放时最好是通过vglobal.removeEventListener TODO - eventManager.globalEventListeners.push({ - name: 'pointerup', - env: 'document', - callback: globalPointerupCallback - }); - //释放时最好是通过vglobal.removeEventListener TODO - eventManager.globalEventListeners.push({ - name: 'pointerdown', - env: 'document', - callback: globalPointerdownCallback - }); - // 整体全局监听事件 - vglobal.addEventListener('pointerup', globalPointerupCallback); - vglobal.addEventListener('pointerdown', globalPointerdownCallback); table.scenegraph.tableGroup.addEventListener('pointerdown', (e: FederatedPointerEvent) => { if ((table as any).hasListeners(TABLE_EVENT_TYPE.MOUSEDOWN_TABLE)) { table.fireListeners(TABLE_EVENT_TYPE.MOUSEDOWN_TABLE, { diff --git a/packages/vtable/src/event/listener/touch.ts b/packages/vtable/src/event/listener/touch.ts index 6ba0b089c0..755fdaab56 100644 --- a/packages/vtable/src/event/listener/touch.ts +++ b/packages/vtable/src/event/listener/touch.ts @@ -1,3 +1,4 @@ +import { vglobal } from '@src/vrender'; import type { FederatedPointerEvent } from '@src/vrender'; import { handleWhell, isHorizontalScrollable, isVerticalScrollable } from '../scroll'; import type { EventManager } from '../event'; @@ -15,9 +16,10 @@ export function bindTouchListener(eventManager: EventManager) { return; } eventManager.isTouchdown = true; + const touchEvent = e.nativeEvent as TouchEvent; eventManager.touchMovePoints.push({ - x: e.page.x, - y: e.page.y, + x: (touchEvent.changedTouches?.[0] as any)?._canvasX ?? e.canvas?.x ?? e.page.x, + y: (touchEvent.changedTouches?.[0] as any)?._canvasY ?? e.canvas?.y ?? e.page.y, timestamp: Date.now() }); }); @@ -39,8 +41,8 @@ export function bindTouchListener(eventManager: EventManager) { eventManager.touchMovePoints.shift(); } eventManager.touchMovePoints.push({ - x: e.changedTouches[0].pageX, - y: e.changedTouches[0].pageY, + x: (e.changedTouches[0] as any)._canvasX ?? e.changedTouches[0].pageX, + y: (e.changedTouches[0] as any)._canvasY ?? e.changedTouches[0].pageY, timestamp: Date.now() }); if (eventManager._enableTableScroll) { @@ -63,10 +65,10 @@ export function bindTouchListener(eventManager: EventManager) { } } }; - window.addEventListener('touchmove', globalTouchMoveCallback, { passive: false }); + vglobal.addEventListener('touchmove', globalTouchMoveCallback, { passive: false }); eventManager.globalEventListeners.push({ name: 'touchmove', - env: 'window', + env: 'vglobal', callback: globalTouchMoveCallback }); @@ -85,8 +87,8 @@ export function bindTouchListener(eventManager: EventManager) { eventManager.touchMovePoints.shift(); } eventManager.touchMovePoints.push({ - x: e.changedTouches[0].pageX, - y: e.changedTouches[0].pageY, + x: (e.changedTouches[0] as any)._canvasX ?? e.changedTouches[0].pageX, + y: (e.changedTouches[0] as any)._canvasY ?? e.changedTouches[0].pageY, timestamp: Date.now() }); // compute inertia parameter @@ -107,10 +109,10 @@ export function bindTouchListener(eventManager: EventManager) { eventManager.isTouchdown = false; eventManager.touchMovePoints = []; }; - window.addEventListener('touchend', globalTouchEndCallback); + vglobal.addEventListener('touchend', globalTouchEndCallback); eventManager.globalEventListeners.push({ name: 'touchend', - env: 'window', + env: 'vglobal', callback: globalTouchEndCallback }); @@ -123,10 +125,10 @@ export function bindTouchListener(eventManager: EventManager) { eventManager.isTouchdown = false; eventManager.touchMovePoints = []; }; - window.addEventListener('touchcancel', globalTouchCancelCallback); + vglobal.addEventListener('touchcancel', globalTouchCancelCallback); eventManager.globalEventListeners.push({ name: 'touchcancel', - env: 'window', + env: 'vglobal', callback: globalTouchCancelCallback }); }