Skip to content

Commit 8323848

Browse files
ZivvWDymoneLewis
authored andcommitted
fix(extension): selection-select 插件在开启选区后,无法通过点击其他地方关闭选区
1 parent f0dfa79 commit 8323848

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

packages/core/src/view/overlay/ToolOverlay.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,10 @@ export class ToolOverlay extends Component<IProps> {
5454
}
5555

5656
zoomHandler = (e: WheelEvent) => {
57+
// TODO 是否应该使用 dispatchEvent 来触发事件
5758
this.props.getCanvasOverlay()?.zoomHandler(e)
5859
}
5960

60-
mouseDownHandler = (e: MouseEvent) => {
61-
this.props.getCanvasOverlay()?.mouseDownHandler(e)
62-
}
63-
6461
render() {
6562
const { graphModel } = this.props
6663
return (
@@ -69,11 +66,10 @@ export class ToolOverlay extends Component<IProps> {
6966
id={`ToolOverlay_${graphModel.flowId}`}
7067
/*
7168
* 默认情况下该容器设置了 pointer-events: none,不会触发这些事件
72-
* 这里会在容器取消 pointer-events: none 后将事件传给画布用来缩放拖拽画布等操作
73-
* 目前只在 selection-select 插件中使用。为了能在元素内部进行框选,在开启选区后会关闭事件透传
69+
* 只会在容器取消 pointer-events: none 后触发,用于缩放、滚动画布等操作
70+
* 目前只在 selection-select 插件中使用。为了能在元素内部进行框选,在开启选区后会关闭事件透传。需要手动触发事件
7471
*/
7572
onWheel={this.zoomHandler}
76-
onMouseDown={this.mouseDownHandler}
7773
>
7874
{this.getTools()}
7975
</div>

packages/extension/src/components/selection-select/index.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ export class SelectionSelect {
1313
private disabled = true
1414
private isWholeNode = true
1515
private isWholeEdge = true
16+
// 用于区分选区和点击事件
17+
private mouseDownInfo: {
18+
x: number
19+
y: number
20+
time: number
21+
} | null = null
1622

1723
constructor({ lf }: LogicFlow.IExtensionProps) {
1824
this.lf = lf
@@ -23,18 +29,22 @@ export class SelectionSelect {
2329
lf.closeSelectionSelect = () => {
2430
this.closeSelectionSelect()
2531
}
26-
this.onToolContainerMouseDown = this.onToolContainerMouseDown.bind(this)
2732
}
2833

2934
render(_: LogicFlow, domContainer: HTMLElement) {
3035
this.container = domContainer
3136
}
3237

33-
onToolContainerMouseDown(e: MouseEvent) {
38+
onToolContainerMouseDown = (e: MouseEvent) => {
3439
// 避免在其他插件元素上点击时开启选区
3540
if (e.target !== this.container) {
3641
return
3742
}
43+
this.mouseDownInfo = {
44+
x: e.clientX,
45+
y: e.clientY,
46+
time: Date.now(),
47+
}
3848
const lf = this.lf
3949
const domContainer = this.container
4050
if (!domContainer) {
@@ -72,6 +82,22 @@ export class SelectionSelect {
7282
document.addEventListener('mouseup', this.drawOff)
7383
}
7484

85+
onToolContainerMouseUp = (e: MouseEvent) => {
86+
if (this.mouseDownInfo) {
87+
const { x, y, time } = this.mouseDownInfo
88+
const now = Date.now()
89+
// 用 mouseDown 和 mouseUp 的位置偏移及时间间隔来判断是否是点击事件
90+
const isClickEvent =
91+
Math.abs(e.clientX - x) < 10 &&
92+
Math.abs(e.clientY - y) < 10 &&
93+
now - time < 100
94+
if (isClickEvent) {
95+
this.lf.clearSelectElements()
96+
}
97+
this.mouseDownInfo = null
98+
}
99+
}
100+
75101
/**
76102
* 设置选中的灵敏度
77103
* @param isWholeEdge 是否要边的起点终点都在选区范围才算选中。默认true
@@ -92,7 +118,9 @@ export class SelectionSelect {
92118
if (!this.container) {
93119
return
94120
}
121+
this.mouseDownInfo = null
95122
this.container.addEventListener('mousedown', this.onToolContainerMouseDown)
123+
this.container.addEventListener('mouseup', this.onToolContainerMouseUp)
96124
// 取消点击事件的穿透,只让 ToolOverlay 接收事件,避免与图形元素的事件冲突
97125
this.container.style.pointerEvents = 'auto'
98126
this.open()
@@ -106,10 +134,12 @@ export class SelectionSelect {
106134
return
107135
}
108136
this.container.style.pointerEvents = 'none'
137+
this.mouseDownInfo = null
109138
this.container.removeEventListener(
110139
'mousedown',
111140
this.onToolContainerMouseDown,
112141
)
142+
this.container.removeEventListener('mouseup', this.onToolContainerMouseUp)
113143
this.close()
114144
}
115145

0 commit comments

Comments
 (0)