@logicflow/core 2.2.0-alpha.1 → 2.2.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/.turbo/turbo-build$colon$dev.log +2 -57
  2. package/.turbo/turbo-build.log +6 -6
  3. package/CHANGELOG.md +12 -0
  4. package/dist/index.css +3 -2
  5. package/dist/index.min.js +1 -1
  6. package/dist/index.min.js.map +1 -1
  7. package/es/LogicFlow.d.ts +9 -0
  8. package/es/constant/index.d.ts +1 -1
  9. package/es/constant/index.js +1 -1
  10. package/es/constant/theme.d.ts +136 -0
  11. package/es/constant/theme.js +680 -0
  12. package/es/index.css +3 -2
  13. package/es/model/GraphModel.d.ts +9 -2
  14. package/es/model/GraphModel.js +17 -6
  15. package/es/model/TransformModel.js +9 -9
  16. package/es/model/edge/BaseEdgeModel.js +7 -2
  17. package/es/model/edge/PolylineEdgeModel.d.ts +6 -0
  18. package/es/model/edge/PolylineEdgeModel.js +23 -1
  19. package/es/model/node/BaseNodeModel.d.ts +12 -1
  20. package/es/model/node/BaseNodeModel.js +6 -1
  21. package/es/model/node/HtmlNodeModel.d.ts +12 -0
  22. package/es/model/node/HtmlNodeModel.js +19 -0
  23. package/es/model/node/PolygonNodeModel.js +3 -3
  24. package/es/options.d.ts +1 -1
  25. package/es/style/index.css +3 -2
  26. package/es/style/index.less +3 -2
  27. package/es/style/raw.d.ts +1 -1
  28. package/es/style/raw.js +1 -1
  29. package/es/tool/MultipleSelectTool.js +6 -5
  30. package/es/util/edge.d.ts +1 -1
  31. package/es/util/edge.js +2 -2
  32. package/es/util/geometry.d.ts +8 -0
  33. package/es/util/geometry.js +79 -0
  34. package/es/util/theme.d.ts +2 -65
  35. package/es/util/theme.js +4 -281
  36. package/es/view/Control.d.ts +5 -0
  37. package/es/view/Control.js +44 -57
  38. package/es/view/edge/PolylineEdge.js +13 -2
  39. package/es/view/node/BaseNode.d.ts +1 -0
  40. package/es/view/node/BaseNode.js +14 -10
  41. package/es/view/node/HtmlNode.js +2 -4
  42. package/es/view/overlay/Grid.d.ts +12 -1
  43. package/es/view/overlay/Grid.js +85 -23
  44. package/es/view/overlay/OutlineOverlay.d.ts +1 -0
  45. package/es/view/overlay/OutlineOverlay.js +17 -16
  46. package/es/view/overlay/gridConfig.d.ts +46 -0
  47. package/es/view/overlay/gridConfig.js +99 -0
  48. package/es/view/shape/Polygon.d.ts +0 -7
  49. package/es/view/shape/Polygon.js +12 -43
  50. package/lib/LogicFlow.d.ts +9 -0
  51. package/lib/constant/index.d.ts +1 -1
  52. package/lib/constant/index.js +16 -2
  53. package/lib/constant/theme.d.ts +136 -0
  54. package/lib/constant/theme.js +683 -0
  55. package/lib/index.css +3 -2
  56. package/lib/model/GraphModel.d.ts +9 -2
  57. package/lib/model/GraphModel.js +18 -7
  58. package/lib/model/TransformModel.js +9 -9
  59. package/lib/model/edge/BaseEdgeModel.js +7 -2
  60. package/lib/model/edge/PolylineEdgeModel.d.ts +6 -0
  61. package/lib/model/edge/PolylineEdgeModel.js +23 -1
  62. package/lib/model/node/BaseNodeModel.d.ts +12 -1
  63. package/lib/model/node/BaseNodeModel.js +6 -1
  64. package/lib/model/node/HtmlNodeModel.d.ts +12 -0
  65. package/lib/model/node/HtmlNodeModel.js +19 -0
  66. package/lib/model/node/PolygonNodeModel.js +3 -3
  67. package/lib/options.d.ts +1 -1
  68. package/lib/style/index.css +3 -2
  69. package/lib/style/index.less +3 -2
  70. package/lib/style/raw.d.ts +1 -1
  71. package/lib/style/raw.js +1 -1
  72. package/lib/tool/MultipleSelectTool.js +6 -5
  73. package/lib/util/edge.d.ts +1 -1
  74. package/lib/util/edge.js +2 -2
  75. package/lib/util/geometry.d.ts +8 -0
  76. package/lib/util/geometry.js +81 -1
  77. package/lib/util/theme.d.ts +2 -65
  78. package/lib/util/theme.js +15 -292
  79. package/lib/view/Control.d.ts +5 -0
  80. package/lib/view/Control.js +44 -57
  81. package/lib/view/edge/PolylineEdge.js +13 -2
  82. package/lib/view/node/BaseNode.d.ts +1 -0
  83. package/lib/view/node/BaseNode.js +14 -10
  84. package/lib/view/node/HtmlNode.js +1 -3
  85. package/lib/view/overlay/Grid.d.ts +12 -1
  86. package/lib/view/overlay/Grid.js +83 -21
  87. package/lib/view/overlay/OutlineOverlay.d.ts +1 -0
  88. package/lib/view/overlay/OutlineOverlay.js +17 -16
  89. package/lib/view/overlay/gridConfig.d.ts +46 -0
  90. package/lib/view/overlay/gridConfig.js +104 -0
  91. package/lib/view/shape/Polygon.d.ts +0 -7
  92. package/lib/view/shape/Polygon.js +13 -45
  93. package/package.json +1 -1
  94. package/src/LogicFlow.tsx +10 -0
  95. package/src/constant/index.ts +2 -2
  96. package/src/constant/theme.ts +708 -0
  97. package/src/model/GraphModel.ts +19 -7
  98. package/src/model/TransformModel.ts +9 -9
  99. package/src/model/edge/BaseEdgeModel.ts +10 -2
  100. package/src/model/edge/PolylineEdgeModel.ts +26 -1
  101. package/src/model/node/BaseNodeModel.ts +9 -1
  102. package/src/model/node/HtmlNodeModel.ts +14 -0
  103. package/src/model/node/PolygonNodeModel.ts +2 -0
  104. package/src/options.ts +1 -1
  105. package/src/style/index.less +3 -2
  106. package/src/style/raw.ts +3 -2
  107. package/src/tool/MultipleSelectTool.tsx +6 -5
  108. package/src/util/edge.ts +2 -1
  109. package/src/util/geometry.ts +99 -0
  110. package/src/util/theme.ts +12 -303
  111. package/src/view/Control.tsx +61 -63
  112. package/src/view/edge/PolylineEdge.tsx +14 -2
  113. package/src/view/node/BaseNode.tsx +8 -3
  114. package/src/view/node/HtmlNode.tsx +27 -10
  115. package/src/view/overlay/Grid.tsx +187 -30
  116. package/src/view/overlay/OutlineOverlay.tsx +35 -47
  117. package/src/view/overlay/gridConfig.ts +103 -0
  118. package/src/view/shape/Polygon.tsx +12 -49
  119. package/stats.html +1 -1
package/src/util/theme.ts CHANGED
@@ -1,312 +1,21 @@
1
1
  import { cloneDeep, merge, assign } from 'lodash-es'
2
2
  import LogicFlow from '../LogicFlow'
3
-
4
- export const defaultTheme: LogicFlow.Theme = {
5
- baseNode: {
6
- fill: '#fff',
7
- stroke: '#000',
8
- strokeWidth: 2,
9
- },
10
-
11
- baseEdge: {
12
- stroke: '#000',
13
- strokeWidth: 2,
14
- },
15
-
16
- rect: {},
17
- circle: {},
18
- diamond: {},
19
- ellipse: {},
20
- polygon: {},
21
-
22
- text: {
23
- color: '#000',
24
- stroke: 'none',
25
- fontSize: 12,
26
- background: {
27
- fill: 'transparent',
28
- },
29
- },
30
-
31
- anchor: {
32
- stroke: '#000',
33
- fill: '#fff',
34
- r: 4,
35
- hover: {
36
- r: 10,
37
- fill: '#949494',
38
- fillOpacity: 0.5,
39
- stroke: '#949494',
40
- },
41
- },
42
-
43
- anchorLine: {
44
- stroke: '#000',
45
- strokeWidth: 2,
46
- strokeDasharray: '3,2',
47
- },
48
-
49
- nodeText: {
50
- color: '#000',
51
- overflowMode: 'default',
52
- fontSize: 12,
53
- lineHeight: 1.2,
54
- },
55
-
56
- edgeText: {
57
- textWidth: 100,
58
- overflowMode: 'default',
59
- fontSize: 12,
60
- background: {
61
- fill: '#fff',
62
- },
63
- },
64
-
65
- line: {},
66
- polyline: {},
67
-
68
- bezier: {
69
- fill: 'none',
70
- adjustLine: {
71
- stroke: '#949494',
72
- },
73
- adjustAnchor: {
74
- r: 4,
75
- fill: '#949494',
76
- fillOpacity: 1,
77
- stroke: '#949494',
78
- },
79
- },
80
-
81
- arrow: {
82
- offset: 10,
83
- verticalLength: 5, // 箭头垂直于边的距离
84
- },
85
-
86
- snapline: {
87
- stroke: '#949494',
88
- strokeWidth: 1,
89
- },
90
-
91
- edgeAdjust: {
92
- r: 4,
93
- fill: '#fff',
94
- stroke: '#949494',
95
- strokeWidth: 2,
96
- },
97
-
98
- outline: {
99
- fill: 'transparent',
100
- stroke: '#949494',
101
- strokeDasharray: '3,3',
102
- hover: {
103
- stroke: '#949494',
104
- },
105
- },
106
-
107
- edgeAnimation: {
108
- stroke: 'red',
109
- strokeDasharray: '10,10',
110
- strokeDashoffset: '100%',
111
- animationName: 'lf_animate_dash',
112
- animationDuration: '20s',
113
- animationIterationCount: 'infinite',
114
- animationTimingFunction: 'linear',
115
- animationDirection: 'normal',
116
- },
117
-
118
- rotateControl: {
119
- stroke: '#000',
120
- fill: '#fff',
121
- strokeWidth: 1.5,
122
- },
123
-
124
- resizeControl: {
125
- width: 7,
126
- height: 7,
127
- fill: '#fff',
128
- stroke: '#000',
129
- },
130
-
131
- resizeOutline: {
132
- fill: 'none',
133
- stroke: 'transparent', // 矩形默认不显示调整边框
134
- strokeWidth: 1,
135
- strokeDasharray: '3,3',
136
- },
137
- }
138
- export const radiusMode: any = {
139
- rect: { radius: 8 },
140
- diamond: { radius: 8 },
141
- polygon: { radius: 8 },
142
- polyline: { radius: 8 },
143
- arrow: {
144
- strokeLinecap: 'round',
145
- strokeLinejoin: 'round',
146
- offset: 10,
147
- verticalLength: 5, // 箭头垂直于边的距离
148
- },
149
- snapline: {
150
- strokeLinecap: 'round',
151
- strokeLinejoin: 'round',
152
- stroke: '#949494',
153
- strokeWidth: 1,
154
- },
155
- outline: {
156
- radius: 8,
157
- fill: 'transparent',
158
- stroke: '#949494',
159
- strokeDasharray: '3,3',
160
- hover: {
161
- stroke: '#949494',
162
- },
163
- },
164
- resizeOutline: {
165
- radius: 8,
166
- fill: 'none',
167
- stroke: 'transparent', // 矩形默认不显示调整边框
168
- strokeWidth: 1,
169
- strokeDasharray: '3,3',
170
- },
171
- }
172
- export const darkMode: any = {
173
- baseNode: {
174
- fill: '#23272e',
175
- stroke: '#fefeff',
176
- },
177
- baseEdge: {
178
- stroke: '#fefeff',
179
- },
180
- rect: { radius: 8 },
181
- diamond: { radius: 8 },
182
- polygon: { radius: 8 },
183
- polyline: { radius: 8 },
184
- nodeText: {
185
- color: '#fefeff',
186
- overflowMode: 'default',
187
- fontSize: 12,
188
- lineHeight: 1.2,
189
- },
190
- arrow: {
191
- strokeLinecap: 'round',
192
- strokeLinejoin: 'round',
193
- offset: 10,
194
- verticalLength: 5, // 箭头垂直于边的距离
195
- },
196
- snapline: {
197
- strokeLinecap: 'round',
198
- strokeLinejoin: 'round',
199
- stroke: '#949494',
200
- strokeWidth: 1,
201
- },
202
- outline: {
203
- radius: 8,
204
- fill: 'transparent',
205
- stroke: '#949494',
206
- strokeDasharray: '3,3',
207
- hover: {
208
- stroke: '#949494',
209
- },
210
- },
211
- resizeOutline: {
212
- radius: 8,
213
- fill: 'none',
214
- stroke: 'transparent', // 矩形默认不显示调整边框
215
- strokeWidth: 1,
216
- strokeDasharray: '3,3',
217
- },
218
- }
219
- export const colorfulMode: any = {
220
- rect: { fill: '#72CBFF', stroke: '#3ABDF9', radius: 8 },
221
- circle: { fill: '#FFE075', stroke: '#F9CE3A', radius: 8 },
222
- ellipse: { fill: '#FFA8A8', stroke: '#FF6B66', radius: 8 },
223
- text: { fill: '#72CBFF', radius: 8 },
224
- diamond: { fill: '#96F7AF', stroke: '#40EF7E', radius: 8 },
225
- polygon: { fill: '#E0A8FF', stroke: '#C271FF', radius: 8 },
226
- polyline: { radius: 8 },
227
- arrow: {
228
- strokeLinecap: 'round',
229
- strokeLinejoin: 'round',
230
- offset: 10,
231
- verticalLength: 5, // 箭头垂直于边的距离
232
- },
233
- snapline: {
234
- strokeLinecap: 'round',
235
- strokeLinejoin: 'round',
236
- stroke: '#949494',
237
- strokeWidth: 1,
238
- },
239
- outline: {
240
- radius: 8,
241
- fill: 'transparent',
242
- stroke: '#949494',
243
- strokeDasharray: '3,3',
244
- hover: {
245
- stroke: '#949494',
246
- },
247
- },
248
- resizeOutline: {
249
- radius: 8,
250
- fill: 'none',
251
- stroke: 'transparent', // 矩形默认不显示调整边框
252
- strokeWidth: 1,
253
- strokeDasharray: '3,3',
254
- },
255
- }
256
-
257
- export const themeModeMap = {
258
- colorful: colorfulMode,
259
- dark: darkMode,
260
- radius: radiusMode,
261
- default: defaultTheme,
262
- }
263
-
264
- // 不同主题的背景色
265
- export const darkBackground = {
266
- background: '#23272e',
267
- }
268
- export const colorfulBackground = {
269
- background: '#fefeff',
270
- }
271
- export const defaultBackground = {
272
- background: '#ffffff',
273
- }
274
- export const backgroundModeMap = {
275
- colorful: colorfulBackground,
276
- dark: darkBackground,
277
- radius: defaultBackground,
278
- default: defaultBackground,
279
- }
280
-
281
- // 不同主题的网格样式
282
- export const darkGrid = {
283
- color: '#66676a',
284
- thickness: 1,
285
- }
286
- export const colorfulGrid = {
287
- color: '#dadada',
288
- thickness: 1,
289
- }
290
- export const defaultGrid = {
291
- color: '#acacac',
292
- thickness: 1,
293
- }
294
- export const gridModeMap = {
295
- colorful: colorfulGrid,
296
- dark: darkGrid,
297
- radius: defaultGrid,
298
- default: defaultGrid,
299
- }
3
+ import {
4
+ themeModeMap,
5
+ backgroundModeMap,
6
+ defaultBackground,
7
+ gridModeMap,
8
+ defaultGrid,
9
+ } from '../constant/theme'
300
10
 
301
11
  /* 主题(全局样式)相关工具方法 */
302
12
  export const setupTheme = (
303
13
  customTheme?: Partial<LogicFlow.Theme>,
304
- themeMode?: 'radius' | 'dark' | 'colorful' | 'default' | string,
14
+ themeMode?: LogicFlow.ThemeMode | string,
305
15
  ): LogicFlow.Theme => {
306
- let theme = cloneDeep(defaultTheme)
307
- if (themeMode) {
308
- theme = merge(theme, themeModeMap[themeMode])
309
- }
16
+ let theme =
17
+ cloneDeep(themeModeMap[themeMode || 'default']) ||
18
+ cloneDeep(themeModeMap.default)
310
19
  if (customTheme) {
311
20
  /**
312
21
  * 为了不让默认样式被覆盖,使用 merge 方法
@@ -363,7 +72,7 @@ export const clearThemeMode = (): void => {
363
72
  const resetTheme = {
364
73
  colorful: {},
365
74
  dark: {},
366
- radius: {},
75
+ retro: {},
367
76
  default: {},
368
77
  }
369
78
  assign(themeModeMap, resetTheme)
@@ -286,61 +286,6 @@ export class ResizeControl extends Component<
286
286
  this.dragHandler.cancelDrag()
287
287
  },
288
288
  })
289
- // 1. 计算当前 Control 的一些信息,
290
- // const {
291
- // r, // circle
292
- // rx, // ellipse/diamond
293
- // ry,
294
- // width, // rect/html
295
- // height,
296
- // PCTResizeInfo,
297
- //
298
- // minWidth,
299
- // minHeight,
300
- // maxWidth,
301
- // maxHeight,
302
- // } = this.nodeModel
303
- // const isFreezeWidth = minWidth === maxWidth
304
- // const isFreezeHeight = minHeight === maxHeight
305
- //
306
- // const resizeInfo = {
307
- // width: r || rx || width,
308
- // height: r || ry || height,
309
- // deltaX,
310
- // deltaY,
311
- // PCTResizeInfo,
312
- // }
313
- //
314
- // const pct = r || (rx && ry) ? 1 / 2 : 1
315
- // const nextSize = this.recalcResizeInfo(
316
- // this.index,
317
- // resizeInfo,
318
- // pct,
319
- // isFreezeWidth,
320
- // isFreezeHeight,
321
- // )
322
- //
323
- // // 限制放大缩小的最大最小范围
324
- // if (
325
- // nextSize.width < minWidth ||
326
- // nextSize.width > maxWidth ||
327
- // nextSize.height < minHeight ||
328
- // nextSize.height > maxHeight
329
- // ) {
330
- // this.dragHandler.cancelDrag()
331
- // return
332
- // }
333
- // // 如果限制了宽高不变,对应的 x/y 不产生位移
334
- // nextSize.deltaX = isFreezeWidth ? 0 : nextSize.deltaX
335
- // nextSize.deltaY = isFreezeWidth ? 0 : nextSize.deltaY
336
- //
337
- // const preNodeData = this.nodeModel.getData()
338
- // const curNodeData = this.nodeModel.resize(nextSize)
339
- //
340
- // // 更新边
341
- // this.updateEdgePointByAnchors()
342
- // // 触发 resize 事件
343
- // this.triggerResizeEvent(preNodeData, curNodeData, deltaX, deltaY, this.index, this.nodeModel)
344
289
  }
345
290
 
346
291
  onDragStart = () => {
@@ -372,28 +317,70 @@ export class ResizeControl extends Component<
372
317
  this.updateEdgePointByAnchors()
373
318
  }
374
319
 
320
+ onPointerDown = (e: PointerEvent) => {
321
+ e.stopPropagation()
322
+ this.dragHandler.handleMouseDown(e)
323
+ }
324
+
325
+ getViewPosition(direction, x, y) {
326
+ const { width = 8, height = 8 } = this.props.model.getResizeControlStyle()
327
+ switch (direction) {
328
+ case 'nw':
329
+ return {
330
+ x: x - width / 2,
331
+ y: y - height / 2,
332
+ }
333
+ case 'ne': {
334
+ return {
335
+ x: x + width / 2,
336
+ y: y - height / 2,
337
+ }
338
+ }
339
+ case 'se': {
340
+ return {
341
+ x: x + width / 2,
342
+ y: y + height / 2,
343
+ }
344
+ }
345
+ case 'sw': {
346
+ return {
347
+ x: x - width / 2,
348
+ y: y + height / 2,
349
+ }
350
+ }
351
+ default: {
352
+ return {
353
+ x,
354
+ y,
355
+ }
356
+ }
357
+ }
358
+ }
359
+
375
360
  render(): h.JSX.Element {
376
361
  const { x, y, direction, model } = this.props
377
362
  const { width, height, ...restStyle } = model.getResizeControlStyle()
363
+ // 为了让调整点在视觉上在调整外框的中间,因此在渲染时转换一下
364
+ const { x: viewX, y: viewY } = this.getViewPosition(direction, x, y)
378
365
  return (
379
366
  <g className={`lf-resize-control lf-resize-control-${direction}`}>
380
367
  <Rect
381
368
  className="lf-resize-control-content"
382
- x={x}
383
- y={y}
369
+ x={viewX}
370
+ y={viewY}
384
371
  width={width ?? 7}
385
372
  height={height ?? 7}
386
373
  {...restStyle}
387
374
  />
388
375
  <Rect
389
376
  className="lf-resize-control-content"
390
- x={x}
391
- y={y}
392
- width={25}
393
- height={25}
377
+ x={viewX}
378
+ y={viewY}
379
+ width={width ? width + 5 : 25}
380
+ height={width ? width + 5 : 25}
394
381
  fill="transparent"
395
382
  stroke="transparent"
396
- onPointerDown={this.dragHandler.handleMouseDown}
383
+ onPointerDown={this.onPointerDown}
397
384
  />
398
385
  </g>
399
386
  )
@@ -451,7 +438,18 @@ export class ResizeControlGroup extends Component<IResizeControlGroupProps> {
451
438
  const { model } = this.props
452
439
  const { x, y, width, height } = model
453
440
  const style = model.getResizeOutlineStyle()
454
- return <Rect {...style} x={x} y={y} width={width} height={height} />
441
+
442
+ return (
443
+ <Rect
444
+ {...style}
445
+ pointer-events="none"
446
+ x={x}
447
+ y={y}
448
+ // TODO:宽高padding后续改成配置化的
449
+ width={width + 10}
450
+ height={height + 10}
451
+ />
452
+ )
455
453
  }
456
454
 
457
455
  render(): h.JSX.Element {
@@ -5,6 +5,7 @@ import LogicFlow from '../../LogicFlow'
5
5
  import { GraphModel, PolylineEdgeModel } from '../../model'
6
6
  import { EventType, SegmentDirection } from '../../constant'
7
7
  import { StepDrag, points2PointsList } from '../../util'
8
+ import { generateRoundedCorners } from '../../util/geometry'
8
9
  import { getVerticalPointOfLine } from '../../algorithm'
9
10
 
10
11
  import ArrowInfo = LogicFlow.ArrowInfo
@@ -110,7 +111,7 @@ export class PolylineEdge extends BaseEdge<IPolylineEdgeProps> {
110
111
  */
111
112
  getEdge() {
112
113
  const { model } = this.props
113
- const { points, isAnimation, arrowConfig } = model
114
+ const { points, isAnimation, arrowConfig, properties } = model
114
115
  const style = model.getEdgeStyle()
115
116
  const animationStyle = model.getEdgeAnimationStyle()
116
117
  const {
@@ -123,9 +124,20 @@ export class PolylineEdge extends BaseEdge<IPolylineEdgeProps> {
123
124
  animationTimingFunction,
124
125
  animationDirection,
125
126
  } = animationStyle
127
+ // 应用通用圆角:当存在样式半径时,为折线拐点生成圆角
128
+ const radius: number = (properties?.radius ??
129
+ (style as any)?.radius ??
130
+ 0) as number
131
+ const roundedPointsStr = (() => {
132
+ if (!radius || radius <= 0) return points
133
+ const list = points2PointsList(points)
134
+ const rounded = generateRoundedCorners(list, radius, false)
135
+ return rounded.map((p) => `${p.x},${p.y}`).join(' ')
136
+ })()
137
+
126
138
  return (
127
139
  <Polyline
128
- points={points}
140
+ points={roundedPointsStr}
129
141
  {...style}
130
142
  {...arrowConfig}
131
143
  {...(isAnimation
@@ -43,6 +43,7 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
43
43
  startTime?: number
44
44
  modelDisposer: IReactionDisposer
45
45
  longPressTimer?: number
46
+ mouseDownPosition?: LogicFlow.Position
46
47
 
47
48
  constructor(props: IProps) {
48
49
  super()
@@ -248,8 +249,11 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
248
249
  height,
249
250
  gridSize,
250
251
  } = graphModel
251
- model.isDragging = true
252
252
  const { clientX, clientY } = event!
253
+ const { x: mouseDownX, y: mouseDownY } = this.mouseDownPosition!
254
+ if (clientX - mouseDownX > gridSize || clientY - mouseDownY > gridSize) {
255
+ model.isDragging = true
256
+ }
253
257
  let {
254
258
  canvasOverlayPosition: { x, y },
255
259
  } = graphModel.getPointByClient({
@@ -347,7 +351,7 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
347
351
  const { model, graphModel } = this.props
348
352
  // 这里会有一种极端情况:当网格大小是1或者关闭网格吸附时,用触摸板点击节点会触发拖拽事件导致节点无法选中
349
353
  // 当触摸板点击节点时,为了防止误触发拖拽导致节点无法选中,允许在非拖拽状态且时间间隔小于100ms时触发点击事件
350
- if (!isDragging && timeInterval > 100) return
354
+ if (!isDragging && timeInterval > 300) return
351
355
  if (!isDragging) {
352
356
  this.onDragEnd()
353
357
  this.handleMouseUp()
@@ -438,6 +442,7 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
438
442
 
439
443
  handleMouseDown = (ev: PointerEvent) => {
440
444
  const { model, graphModel } = this.props
445
+ this.mouseDownPosition = { x: ev.clientX, y: ev.clientY }
441
446
  this.startTime = new Date().getTime()
442
447
  const { editConfigModel } = graphModel
443
448
  if (editConfigModel.adjustNodePosition && model.draggable) {
@@ -524,8 +529,8 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
524
529
  <g transform={transform}>
525
530
  {this.getShape()}
526
531
  {this.getText()}
527
- {allowRotate && this.getRotateControl()}
528
532
  {allowResize && this.getResizeControl()}
533
+ {allowRotate && this.getRotateControl()}
529
534
  </g>
530
535
  {!hideAnchors && this.getAnchors()}
531
536
  </g>
@@ -54,14 +54,12 @@ export class HtmlNode<
54
54
  }
55
55
 
56
56
  componentDidMount() {
57
- // console.log('HtmlNode --->>> componentDidMount - 初始化内容')
58
57
  if (this.shouldUpdate() && this.rootEl) {
59
58
  this.setHtml(this.rootEl)
60
59
  }
61
60
  }
62
61
 
63
62
  componentDidUpdate() {
64
- // console.log('HtmlNode --->>> componentDidUpdate - 更新节点内容')
65
63
  // DONE: 将 componentDidMount 和 componentDidUpdate 区分开,如果写在一次,渲染 React 组件会重复初始化,消耗过多资源
66
64
  // 为了保证历史兼容性,先将默认 HTML 节点的 setHtml 和 confirmUpdate 保持一直,用户可通过自定义的方式重新定义
67
65
  if (this.shouldUpdate() && this.rootEl) {
@@ -80,14 +78,33 @@ export class HtmlNode<
80
78
  const style = model.getNodeStyle()
81
79
  this.currentProperties = JSON.stringify(model.properties)
82
80
  return (
83
- <foreignObject
84
- {...style}
85
- x={x - width / 2}
86
- y={y - height / 2}
87
- width={width}
88
- height={height}
89
- ref={this.ref}
90
- />
81
+ <g>
82
+ {style.shadow && (
83
+ <defs>
84
+ <filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
85
+ <feDropShadow {...style.shadow} />
86
+ </filter>
87
+ </defs>
88
+ )}
89
+ <rect
90
+ x={x - width / 2}
91
+ y={y - height / 2}
92
+ width={width}
93
+ height={height}
94
+ rx={style.radius}
95
+ ry={style.radius}
96
+ {...style}
97
+ filter="url(#shadow)"
98
+ />
99
+ <foreignObject
100
+ {...style}
101
+ x={x - width / 2}
102
+ y={y - height / 2}
103
+ width={width}
104
+ height={height}
105
+ ref={this.ref}
106
+ />
107
+ </g>
91
108
  )
92
109
  }
93
110
  }