diff --git a/.gitignore b/.gitignore index b453dbb37..d2b2e9d02 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ pids *.seed *.pid.lock yarn.lock +.dumi # Directory for instrumented libs generated by jscoverage/JSCover lib-cov diff --git a/__tests__/demos/event/dblClick.ts b/__tests__/demos/event/dblClick.ts new file mode 100644 index 000000000..02f771962 --- /dev/null +++ b/__tests__/demos/event/dblClick.ts @@ -0,0 +1,83 @@ +import { Circle, Text } from '../../../packages/g'; + +export async function dblClick(context) { + const { canvas } = context; + await canvas.ready; + + let DELAY = 200; + canvas.dblClickSpeed = DELAY; + + const circle0 = new Circle({ + style: { + cx: 100, + cy: 100, + r: 50, + fill: 'red', + cursor: 'pointer', + }, + }); + const circle1 = new Circle({ + style: { + cx: 300, + cy: 100, + r: 50, + fill: 'red', + cursor: 'pointer', + }, + }); + const circle2 = new Circle({ + style: { + cx: 500, + cy: 100, + r: 50, + fill: 'red', + cursor: 'pointer', + }, + }); + const text0 = new Text({ + style: { x: 0, y: 200, text: `current dblclick delay: ${DELAY}ms` }, + }); + const text1 = new Text({ + style: { x: 0, y: 220, text: `action: ` }, + }); + + circle0.addEventListener('mouseenter', () => { + DELAY = 200; + canvas.dblClickSpeed = DELAY; + + text0.attr({ text: `current dblclick delay: ${DELAY}ms` }); + text1.attr({ + text: `action: `, + }); + }); + circle1.addEventListener('mouseenter', () => { + DELAY = 500; + canvas.dblClickSpeed = DELAY; + + text0.attr({ text: `current dblclick delay: ${DELAY}ms` }); + text1.attr({ + text: `action: `, + }); + }); + circle2.addEventListener('mouseenter', () => { + DELAY = 1000; + canvas.dblClickSpeed = DELAY; + + text0.attr({ text: `current dblclick delay: ${DELAY}ms` }); + text1.attr({ + text: `action: `, + }); + }); + + canvas.addEventListener('click', (event) => { + text1.attr({ + text: `action: ${event.detail === 2 ? 'dblclick' : 'click'}`, + }); + }); + + canvas.appendChild(circle0); + canvas.appendChild(circle1); + canvas.appendChild(circle2); + canvas.appendChild(text0); + canvas.appendChild(text1); +} diff --git a/__tests__/demos/event/index.ts b/__tests__/demos/event/index.ts index bfeb428f0..4e21a86af 100644 --- a/__tests__/demos/event/index.ts +++ b/__tests__/demos/event/index.ts @@ -2,3 +2,4 @@ export { circle } from './circle'; export { ellipse } from './ellipse'; export { hierarchy } from './hierarchy'; export { imageNonTransparentPixel } from './image-non-transparent-pixel'; +export { dblClick } from './dblClick'; diff --git a/packages/g-lite/src/Canvas.ts b/packages/g-lite/src/Canvas.ts index 0f25911ee..8feda3d26 100644 --- a/packages/g-lite/src/Canvas.ts +++ b/packages/g-lite/src/Canvas.ts @@ -120,6 +120,11 @@ export class Canvas extends EventTarget implements ICanvas { */ isMouseEvent: (event: InteractivePointerEvent) => event is MouseEvent; + /** + * double click speed (ms), default is 200ms + */ + dblClickSpeed?: CanvasConfig['dblClickSpeed']; + /** * @see https://developer.mozilla.org/en-US/docs/Web/API/Element */ @@ -168,6 +173,7 @@ export class Canvas extends EventTarget implements ICanvas { alwaysTriggerPointerEventOnCanvas, isTouchEvent, isMouseEvent, + dblClickSpeed, } = config; if (!supportsMutipleCanvasesInOneContainer) { @@ -222,6 +228,8 @@ export class Canvas extends EventTarget implements ICanvas { (!this.supportsPointerEvents || !(event instanceof runtime.globalThis.PointerEvent)))); + this.dblClickSpeed = dblClickSpeed ?? 200; + this.initRenderingContext({ container, canvas, diff --git a/packages/g-lite/src/dom/interfaces.ts b/packages/g-lite/src/dom/interfaces.ts index c93b4e6f2..0b8b47cfc 100644 --- a/packages/g-lite/src/dom/interfaces.ts +++ b/packages/g-lite/src/dom/interfaces.ts @@ -556,6 +556,7 @@ export interface ICanvas extends IEventTarget { supportsPointerEvents: boolean; isTouchEvent: (event: InteractivePointerEvent) => event is TouchEvent; isMouseEvent: (event: InteractivePointerEvent) => event is MouseEvent; + dblClickSpeed?: number; render: () => void; destroy: (destroyScenegraph?: boolean) => void; diff --git a/packages/g-lite/src/services/EventService.ts b/packages/g-lite/src/services/EventService.ts index a003ddadb..8c402a2b9 100644 --- a/packages/g-lite/src/services/EventService.ts +++ b/packages/g-lite/src/services/EventService.ts @@ -311,11 +311,13 @@ export class EventService { }; } + const canvas = + this.context.renderingContext.root.ownerDocument.defaultView; const clickHistory = trackingData.clicksByButton[from.button]; if ( clickHistory.target === clickEvent.target && - now - clickHistory.timeStamp < 200 + now - clickHistory.timeStamp < canvas.dblClickSpeed ) { ++clickHistory.clickCount; } else { diff --git a/packages/g-lite/src/types.ts b/packages/g-lite/src/types.ts index 10998b472..b10c36663 100644 --- a/packages/g-lite/src/types.ts +++ b/packages/g-lite/src/types.ts @@ -447,6 +447,8 @@ export interface CanvasConfig { supportsTouchEvents?: boolean; isTouchEvent?: (event: InteractivePointerEvent) => event is TouchEvent; isMouseEvent?: (event: InteractivePointerEvent) => event is MouseEvent; + dblClickSpeed?: number; + /** * Listen to native click event instead of mocking with pointerup & down events. */ diff --git a/site/docs/api/canvas/options.en.md b/site/docs/api/canvas/options.en.md index 7dbfaf32a..38f4edf39 100644 --- a/site/docs/api/canvas/options.en.md +++ b/site/docs/api/canvas/options.en.md @@ -188,6 +188,10 @@ Optional. Determines if a native event is a TouchEvent, accepts the native event Optional. Determines if a native event is a MouseEvent, accepts the native event as parameter, and returns the result. +### dblClickSpeed + +Optional. Numeric type, determines whether two consecutive clicks trigger a double-click event [dblclick](https://developer.mozilla.org/en-US/docs/Web/API/Element/dblclick_event) , the default is 200 ms. + ### offscreenCanvas Optional. Returns an `HTMLCanvasElement | OffscreenCanvas` or similar object. Used to generate an offscreen Canvas2D context, it is currently used in the following scenarios. diff --git a/site/docs/api/canvas/options.zh.md b/site/docs/api/canvas/options.zh.md index 20f8541aa..ce604d521 100644 --- a/site/docs/api/canvas/options.zh.md +++ b/site/docs/api/canvas/options.zh.md @@ -193,6 +193,10 @@ $wrapper.style.transform = 'scale(1.1)'; 可选。判断一个原生事件是否是 MouseEvent,接受原生事件作为参数,返回判定结果。 +### dblClickSpeed + +可选。数值类型,判断两次连续点击是否触发双击事件 [dblclick](https://developer.mozilla.org/zh-CN/docs/Web/API/Element/dblclick_event) 的速度,默认为 200 ms。 + ### offscreenCanvas 可选。返回一个 `HTMLCanvasElement | OffscreenCanvas` 或类似对象。用于生成一个离屏的 Canvas2D 上下文,目前它使用在以下场景: diff --git a/site/package.json b/site/package.json index 0ba4429d2..81e46e48e 100644 --- a/site/package.json +++ b/site/package.json @@ -26,39 +26,41 @@ }, "dependencies": { "@antv/g": "latest", - "@antv/g-lite": "latest", "@antv/g-canvas": "latest", - "@antv/g-webgl": "latest", - "@antv/g-svg": "latest", - "@antv/g-webgpu": "latest", "@antv/g-canvaskit": "latest", - "@antv/g-plugin-css-select": "latest", + "@antv/g-components": "latest", + "@antv/g-device-api": "latest", + "@antv/g-image-exporter": "latest", + "@antv/g-lite": "latest", + "@antv/g-lottie-player": "latest", + "@antv/g-pattern": "latest", "@antv/g-plugin-3d": "latest", + "@antv/g-plugin-a11y": "latest", + "@antv/g-plugin-annotation": "latest", + "@antv/g-plugin-box2d": "latest", "@antv/g-plugin-control": "latest", - "@antv/g-plugin-gpgpu": "latest", + "@antv/g-plugin-css-select": "latest", + "@antv/g-plugin-device-renderer": "latest", + "@antv/g-plugin-dragndrop": "latest", "@antv/g-plugin-gesture": "latest", - "@antv/g-plugin-physx": "latest", - "@antv/g-plugin-box2d": "latest", + "@antv/g-plugin-gpgpu": "latest", + "@antv/g-plugin-image-loader": "latest", "@antv/g-plugin-matterjs": "latest", - "@antv/g-plugin-yoga": "latest", + "@antv/g-plugin-physx": "latest", "@antv/g-plugin-rough-canvas-renderer": "latest", "@antv/g-plugin-rough-svg-renderer": "latest", "@antv/g-plugin-svg-renderer": "latest", - "@antv/g-plugin-dragndrop": "latest", - "@antv/g-plugin-a11y": "latest", - "@antv/g-plugin-annotation": "latest", + "@antv/g-plugin-yoga": "latest", "@antv/g-plugin-zdog-canvas-renderer": "latest", "@antv/g-plugin-zdog-svg-renderer": "latest", - "@antv/g-plugin-image-loader": "latest", - "@antv/webgpu-graph": "latest", - "@antv/g-components": "latest", + "@antv/g-svg": "latest", "@antv/g-web-components": "latest", - "@antv/g-image-exporter": "latest", - "@antv/g-lottie-player": "latest", - "@antv/g-pattern": "latest", - "@antv/react-g": "latest", + "@antv/g-webgl": "latest", + "@antv/g-webgpu": "latest", "@antv/g6": "^4.5.2", + "@antv/react-g": "latest", "@antv/util": "^3.3.5", + "@antv/webgpu-graph": "latest", "@naoak/workerize-transferable": "^0.1.0", "@observablehq/plot": "0.5.2", "@types/gl-matrix": "^2.4.5",