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
});
}