@logicflow/core 2.2.0-alpha.7 → 2.2.1

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 (137) hide show
  1. package/package.json +6 -1
  2. package/.turbo/turbo-build$colon$dev.log +0 -10
  3. package/.turbo/turbo-build.log +0 -33
  4. package/CHANGELOG.md +0 -1901
  5. package/__tests__/algorithm/egde.test.ts +0 -131
  6. package/__tests__/algorithm/index.test.ts +0 -74
  7. package/__tests__/algorithm/outline.test.ts +0 -43
  8. package/__tests__/bugs/1545-spec.test.ts +0 -42
  9. package/__tests__/event/event.test.ts +0 -22
  10. package/__tests__/history/history.test.ts +0 -28
  11. package/__tests__/logicflow.test.ts +0 -575
  12. package/__tests__/model/graphmodel.test.ts +0 -87
  13. package/__tests__/util/compatible.test.ts +0 -48
  14. package/__tests__/util/edge.test.ts +0 -224
  15. package/__tests__/util/geometry.test.ts +0 -14
  16. package/__tests__/util/graph.test.ts +0 -16
  17. package/__tests__/util/matrix.test.ts +0 -41
  18. package/__tests__/util/node.test.ts +0 -68
  19. package/__tests__/util/sampling.test.ts +0 -12
  20. package/__tests__/util/vector.test.ts +0 -50
  21. package/__tests__/util/zIndex.test.ts +0 -10
  22. package/src/LogicFlow.tsx +0 -2017
  23. package/src/algorithm/edge.ts +0 -67
  24. package/src/algorithm/index.ts +0 -70
  25. package/src/algorithm/outline.ts +0 -77
  26. package/src/algorithm/rotate.ts +0 -55
  27. package/src/common/drag.ts +0 -219
  28. package/src/common/history.ts +0 -108
  29. package/src/common/index.ts +0 -6
  30. package/src/common/keyboard.ts +0 -108
  31. package/src/common/matrix.ts +0 -122
  32. package/src/common/vector.ts +0 -93
  33. package/src/constant/index.ts +0 -179
  34. package/src/constant/theme.ts +0 -708
  35. package/src/event/event.md +0 -66
  36. package/src/event/eventArgs.ts +0 -643
  37. package/src/event/eventEmitter.ts +0 -156
  38. package/src/history/index.ts +0 -119
  39. package/src/index.less +0 -1
  40. package/src/index.ts +0 -26
  41. package/src/keyboard/index.ts +0 -112
  42. package/src/keyboard/shortcut.ts +0 -200
  43. package/src/model/BaseModel.ts +0 -250
  44. package/src/model/EditConfigModel.ts +0 -334
  45. package/src/model/GraphModel.ts +0 -1824
  46. package/src/model/NestedTransformModel.ts +0 -121
  47. package/src/model/SnaplineModel.ts +0 -256
  48. package/src/model/TransformModel.ts +0 -258
  49. package/src/model/edge/BaseEdgeModel.ts +0 -785
  50. package/src/model/edge/BezierEdgeModel.ts +0 -197
  51. package/src/model/edge/LineEdgeModel.ts +0 -36
  52. package/src/model/edge/PolylineEdgeModel.ts +0 -817
  53. package/src/model/edge/index.ts +0 -4
  54. package/src/model/index.ts +0 -9
  55. package/src/model/node/BaseNodeModel.ts +0 -959
  56. package/src/model/node/CircleNodeModel.ts +0 -91
  57. package/src/model/node/DiamondNodeModel.ts +0 -132
  58. package/src/model/node/EllipseNodeModel.ts +0 -98
  59. package/src/model/node/HtmlNodeModel.ts +0 -64
  60. package/src/model/node/PolygonNodeModel.ts +0 -152
  61. package/src/model/node/RectNodeModel.ts +0 -69
  62. package/src/model/node/TextNodeModel.ts +0 -54
  63. package/src/model/node/index.ts +0 -8
  64. package/src/options.ts +0 -150
  65. package/src/style/index.less +0 -262
  66. package/src/style/raw.ts +0 -221
  67. package/src/tool/MultipleSelectTool.tsx +0 -140
  68. package/src/tool/TextEditTool.tsx +0 -193
  69. package/src/tool/index.ts +0 -101
  70. package/src/typings.d.ts +0 -5
  71. package/src/util/animation.ts +0 -29
  72. package/src/util/browser.ts +0 -4
  73. package/src/util/compatible.ts +0 -15
  74. package/src/util/drag.ts +0 -219
  75. package/src/util/edge.ts +0 -1094
  76. package/src/util/geometry.ts +0 -154
  77. package/src/util/graph.ts +0 -46
  78. package/src/util/index.ts +0 -17
  79. package/src/util/matrix.ts +0 -129
  80. package/src/util/mobx.ts +0 -23
  81. package/src/util/node.ts +0 -543
  82. package/src/util/raf.ts +0 -28
  83. package/src/util/resize.ts +0 -606
  84. package/src/util/sampling.ts +0 -85
  85. package/src/util/theme.ts +0 -84
  86. package/src/util/uuid.ts +0 -26
  87. package/src/util/vector.ts +0 -93
  88. package/src/util/zIndex.ts +0 -6
  89. package/src/view/Anchor.tsx +0 -462
  90. package/src/view/Control.tsx +0 -510
  91. package/src/view/Graph.tsx +0 -141
  92. package/src/view/Rotate.tsx +0 -113
  93. package/src/view/behavior/dnd.ts +0 -162
  94. package/src/view/behavior/index.ts +0 -2
  95. package/src/view/behavior/snapline.ts +0 -16
  96. package/src/view/edge/AdjustPoint.tsx +0 -425
  97. package/src/view/edge/Arrow.tsx +0 -54
  98. package/src/view/edge/BaseEdge.tsx +0 -660
  99. package/src/view/edge/BezierEdge.tsx +0 -101
  100. package/src/view/edge/LineEdge.tsx +0 -81
  101. package/src/view/edge/PolylineEdge.tsx +0 -311
  102. package/src/view/edge/index.ts +0 -6
  103. package/src/view/index.ts +0 -8
  104. package/src/view/node/BaseNode.tsx +0 -585
  105. package/src/view/node/CircleNode.tsx +0 -21
  106. package/src/view/node/DiamondNode.tsx +0 -24
  107. package/src/view/node/EllipseNode.tsx +0 -22
  108. package/src/view/node/HtmlNode.tsx +0 -112
  109. package/src/view/node/PolygonNode.tsx +0 -28
  110. package/src/view/node/RectNode.tsx +0 -30
  111. package/src/view/node/TextNode.tsx +0 -39
  112. package/src/view/node/index.ts +0 -8
  113. package/src/view/overlay/BackgroundOverlay.tsx +0 -34
  114. package/src/view/overlay/BezierAdjustOverlay.tsx +0 -150
  115. package/src/view/overlay/CanvasOverlay.tsx +0 -290
  116. package/src/view/overlay/Grid.tsx +0 -319
  117. package/src/view/overlay/ModificationOverlay.tsx +0 -31
  118. package/src/view/overlay/OutlineOverlay.tsx +0 -158
  119. package/src/view/overlay/SnaplineOverlay.tsx +0 -44
  120. package/src/view/overlay/ToolOverlay.tsx +0 -65
  121. package/src/view/overlay/getTransformHoc.tsx +0 -50
  122. package/src/view/overlay/gridConfig.ts +0 -103
  123. package/src/view/overlay/index.ts +0 -8
  124. package/src/view/shape/Circle.tsx +0 -41
  125. package/src/view/shape/Ellipse.tsx +0 -42
  126. package/src/view/shape/Line.tsx +0 -39
  127. package/src/view/shape/Path.tsx +0 -22
  128. package/src/view/shape/Polygon.tsx +0 -54
  129. package/src/view/shape/Polyline.tsx +0 -31
  130. package/src/view/shape/Rect.tsx +0 -44
  131. package/src/view/shape/Text.tsx +0 -168
  132. package/src/view/shape/index.ts +0 -8
  133. package/src/view/text/BaseText.tsx +0 -134
  134. package/src/view/text/LineText.tsx +0 -168
  135. package/src/view/text/index.ts +0 -2
  136. package/stats.html +0 -4842
  137. package/tsconfig.json +0 -18
@@ -1,156 +0,0 @@
1
- import { EventArgs } from './eventArgs'
2
-
3
- export type EventType<T extends string = string> = {
4
- readonly callback: EventCallback<T>
5
- readonly once: boolean
6
- }
7
-
8
- export type EventsType<T extends string = string> = {
9
- [k in T]?: EventType<k>[]
10
- }
11
-
12
- export type CallbackArgs<T extends string = string> = T extends keyof EventArgs
13
- ? EventArgs[T]
14
- : // 如果不是内部定义的事件类型,那么允许用户抛出任何类型的参数
15
- // 这部分的类型定义由用户自己来保证
16
- any
17
-
18
- export type EventCallback<T extends string = string> = (
19
- args: CallbackArgs<T>,
20
- ) => void
21
-
22
- const WILDCARD = '*'
23
-
24
- /* event-emitter */
25
- export default class EventEmitter {
26
- private _events: EventsType = {}
27
-
28
- /**
29
- * 监听一个事件
30
- * @param evt 事件名称
31
- * @param callback 回调函数
32
- * @param once 是否只监听一次
33
- */
34
- on<T extends keyof EventArgs>(
35
- evt: T,
36
- callback: EventCallback<T>,
37
- once?: boolean,
38
- ): void
39
- on<T extends string>(evt: T, callback: EventCallback<T>, once?: boolean): void
40
- on(evt: string, callback: EventCallback, once?: boolean) {
41
- evt?.split(',').forEach((evKey) => {
42
- evKey = evKey.trim()
43
- if (!this._events[evKey]) {
44
- this._events[evKey] = []
45
- }
46
- this._events[evKey]!.push({
47
- callback,
48
- once: !!once,
49
- })
50
- })
51
- }
52
-
53
- /**
54
- * 监听一个事件一次
55
- * @param evt 事件名称
56
- * @param callback 回调函数
57
- */
58
- once<T extends keyof EventArgs>(
59
- evt: T,
60
- callback: (args: EventArgs[T]) => void,
61
- ): void
62
- once<T extends string>(evt: T, callback: EventCallback<T>): void
63
- once(evt: string, callback: EventCallback) {
64
- evt?.split(',').forEach((evKey) => {
65
- evKey = evKey.trim()
66
- this.on(evKey, callback, true)
67
- })
68
- }
69
-
70
- /**
71
- * 触发一个事件
72
- * @param evts
73
- * @param eventArgs
74
- */
75
- emit<T extends keyof EventArgs>(evts: T, eventArgs: CallbackArgs<T>): void
76
- emit<T extends string>(evts: T, eventArgs: CallbackArgs<T>): void
77
- emit(evts: string, eventArgs?: EventCallback) {
78
- evts?.split(',').forEach((evt) => {
79
- const events = this._events[evt] || []
80
- const wildcardEvents = this._events[WILDCARD] || []
81
- // 实际的处理 emit 方法
82
- const doEmit = (es: EventType[]) => {
83
- let { length } = es
84
- for (let i = 0; i < length; i++) {
85
- if (!es[i]) {
86
- continue
87
- }
88
- const { callback, once } = es[i]
89
- if (once) {
90
- es.splice(i, 1)
91
- if (es.length === 0) {
92
- delete this._events[evt]
93
- }
94
- length--
95
- i--
96
- }
97
- callback.apply(this, [eventArgs])
98
- }
99
- }
100
- doEmit(events)
101
- doEmit(wildcardEvents)
102
- })
103
- }
104
-
105
- /**
106
- * 取消事件监听
107
- * @param evts 事件名称
108
- * @param callback 回调函数
109
- *
110
- * - evts 为空时,清除所有事件的监听器
111
- * - evts 非空,callback 为空时,清除指定事件的所有监听器
112
- * - evts 非空,callback 非空,进行对象比较,清除指定事件的指定监听器
113
- */
114
- off<T extends keyof EventArgs>(
115
- evts: T,
116
- callback?: (args: EventArgs[T]) => void,
117
- ): void
118
- off<T extends string>(evts: T, callback?: EventCallback<T>): void
119
- off(evts: string, callback?: EventCallback) {
120
- if (!evts) {
121
- // evt 为空全部清除
122
- this._events = {}
123
- }
124
- evts.split(',').forEach((evt) => {
125
- if (!callback) {
126
- // evt 存在,callback 为空,清除事件所有方法
127
- delete this._events[evt]
128
- } else {
129
- // evt 存在,callback 存在,清除匹配的
130
- const events = this._events[evt] || []
131
- let { length } = events
132
- for (let i = 0; i < length; i++) {
133
- if (events[i].callback === callback) {
134
- events.splice(i, 1)
135
- length--
136
- i--
137
- }
138
- }
139
- if (events.length === 0) {
140
- delete this._events[evt]
141
- }
142
- }
143
- })
144
- }
145
-
146
- /* 当前所有的事件 */
147
- getEvents() {
148
- return this._events
149
- }
150
-
151
- destroy() {
152
- this._events = {}
153
- }
154
- }
155
-
156
- export { EventEmitter, EventArgs }
@@ -1,119 +0,0 @@
1
- import { debounce, isEqual, last, cloneDeep } from 'lodash-es'
2
- import { deepObserve, IDisposer } from 'mobx-utils'
3
- import LogicFlow from '..'
4
- import { GraphModel } from '../model'
5
- import { EventType } from '../constant'
6
- import EventEmitter from '../event/eventEmitter'
7
-
8
- import GraphData = LogicFlow.GraphData
9
-
10
- export class History {
11
- undos: GraphData[] = []
12
- redos: GraphData[] = []
13
- callbacks = []
14
- stopWatch: IDisposer | null = null
15
- curData: GraphData | null = null
16
- maxSize = 50
17
- // 发生数据变化后,最多再等500ms,把距离上次的数据变更存储起来。
18
- // 所以waitTime值越小,History对数据变化越敏感,存的undos就越细。
19
- waitTime = 100
20
- eventCenter: EventEmitter
21
-
22
- constructor(eventCenter: EventEmitter) {
23
- this.eventCenter = eventCenter
24
- }
25
-
26
- add(data: GraphData) {
27
- if (isEqual(last(this.undos), data)) return
28
- this.undos.push(data)
29
- // 因为undo的时候,会触发add.
30
- // 所以需要区分这个add是undo触发的,还是用户正常操作触发的。
31
- // 如果是用户正常操作触发的,需要清空redos
32
- if (!isEqual(this.curData, data)) {
33
- this.redos = []
34
- }
35
- this.eventCenter.emit(EventType.HISTORY_CHANGE, {
36
- data: {
37
- undos: this.undos,
38
- redos: this.redos,
39
- undoAble: this.undoAble(),
40
- redoAble: this.redoAble(),
41
- },
42
- })
43
- if (this.undos.length > this.maxSize) {
44
- this.undos.shift()
45
- }
46
- }
47
-
48
- undoAble() {
49
- // undos栈顶就是当前图渲染出来的数据。
50
- return this.undos.length > 1
51
- }
52
-
53
- // 1) undo方法触发
54
- // 2) graphModel重新渲染nodes和edges
55
- // 3) graphModel发生变化,触发watch
56
- // 4) watch触发add
57
- undo() {
58
- if (!this.undoAble()) return
59
- const preData = this.undos.pop()!
60
- this.redos.push(preData)
61
- const curData = this.undos.pop()!
62
- this.curData = cloneDeep(curData)
63
- return curData
64
- }
65
-
66
- redoAble() {
67
- return this.redos.length > 0
68
- }
69
-
70
- redo() {
71
- if (!this.redoAble()) return
72
- const curData = this.redos.pop()!
73
- this.curData = cloneDeep(curData)
74
- return curData
75
- }
76
-
77
- watch(model: GraphModel) {
78
- this.stopWatch && this.stopWatch()
79
-
80
- // 把当前watch的model转换一下数据存起来,无需清空redos。
81
- this.undos.push(model.modelToGraphData())
82
-
83
- this.stopWatch = deepObserve(
84
- // TODO:避免用户触发「The same observable object cannot appear twice in the same tree」 错误
85
- // 例如:在自定义节点的 setAttributes 方法中,将 nodeModel 属性赋值给另一个 observable 属性
86
- // eg:
87
- // setAttributes() {
88
- // this.width = 120
89
- // this.height = 50
90
- //
91
- // if (this.text) {
92
- // this.properties.text = this.text;
93
- // this.text.value = '';
94
- // }
95
- // }
96
- // 解决方案:使用 cloneDeep 方法,将 observable 对象克隆一份。需要测试下面操作是否会造成其它问题
97
- // https://stackoverflow.com/questions/55328504/a-node-cannot-exists-twice-in-the-state-tree-mobx-state-tree
98
- // cloneDeep(model),
99
- model,
100
- debounce(() => {
101
- // 数据变更后,把最新的当前model数据存起来,并清空 redos。
102
- // 因为这个回调函数的触发,一般是用户交互而引起的,所以按正常逻辑需要清空 redos。
103
- const data = model.modelToHistoryData()
104
- if (data) {
105
- this.add({ ...data })
106
- }
107
- }, this.waitTime),
108
- )
109
- }
110
-
111
- destroy() {
112
- this.undos = []
113
- this.redos = []
114
- this.curData = null
115
- this.stopWatch && this.stopWatch()
116
- }
117
- }
118
-
119
- export default History
package/src/index.less DELETED
@@ -1 +0,0 @@
1
- @import url('./style/index');
package/src/index.ts DELETED
@@ -1,26 +0,0 @@
1
- import { observer as mobxObserver } from 'mobx-preact'
2
- import { createElement as h, createRef, Component } from 'preact/compat'
3
- import LogicFlow from './LogicFlow'
4
-
5
- import * as LogicFlowUtil from './util'
6
-
7
- export function observer<P>(props: P) {
8
- return mobxObserver(props as any)
9
- }
10
-
11
- export { LogicFlow, h, createRef, Component, LogicFlowUtil }
12
-
13
- export * from './util'
14
- export * from './tool'
15
- export * from './view'
16
- export * from './model'
17
- export * from './options'
18
- export * from './keyboard'
19
- export * from './constant'
20
- export * from './algorithm'
21
- export * from './event/eventEmitter'
22
- export { ElementState, ModelType, ElementType, EventType } from './constant'
23
-
24
- export { formatAnchorConnectValidateData } from './util/node'
25
-
26
- export default LogicFlow
@@ -1,112 +0,0 @@
1
- import { isArray } from 'lodash-es'
2
- import Mousetrap, { MousetrapInstance } from 'mousetrap'
3
- import LogicFlow from '../LogicFlow'
4
-
5
- export * from './shortcut'
6
-
7
- export type Action = 'keypress' | 'keydown' | 'keyup'
8
- export type Handler = (e: KeyboardEvent) => void
9
-
10
- export interface KeyboardDef {
11
- enabled: boolean
12
- shortcuts?: Array<{
13
- keys: string | string[]
14
- callback: Handler
15
- action?: Action
16
- }>
17
- }
18
-
19
- export interface KeyboardOptions {
20
- lf: LogicFlow
21
- keyboard?: KeyboardDef
22
- }
23
-
24
- export class Keyboard {
25
- public readonly mousetrap: MousetrapInstance
26
- public options: KeyboardOptions
27
- private readonly target: HTMLElement
28
-
29
- constructor(options: KeyboardOptions) {
30
- if (!options.keyboard) {
31
- options.keyboard = { enabled: false }
32
- }
33
- this.options = options
34
- const { lf } = options
35
- this.target = lf.container
36
- this.mousetrap = new Mousetrap(this.target)
37
- // 默认开启快捷键,且不是静默模式时enable
38
- if (options.keyboard.enabled && !lf.options.isSilentMode) {
39
- this.enable(true)
40
- }
41
- }
42
-
43
- initShortcuts() {
44
- const { shortcuts } = this.options.keyboard ?? {}
45
- if (shortcuts) {
46
- if (isArray(shortcuts)) {
47
- shortcuts.forEach(({ keys, callback, action }) =>
48
- this.on(keys, callback, action),
49
- )
50
- } else {
51
- const { keys, callback, action } = shortcuts
52
- this.on(keys, callback, action)
53
- }
54
- }
55
- }
56
-
57
- on(keys: string | string[], callback: Handler, action?: Action) {
58
- this.mousetrap.bind(this.getKeys(keys), callback, action)
59
- }
60
-
61
- get disabled() {
62
- return this.options?.keyboard?.enabled !== true
63
- }
64
-
65
- off(keys: string | string[], action?: Action) {
66
- this.mousetrap.unbind(this.getKeys(keys), action)
67
- }
68
-
69
- enable(force: boolean) {
70
- if (this.disabled || force) {
71
- if (this.options.keyboard) {
72
- this.options.keyboard.enabled = true
73
- }
74
- if (this.target instanceof HTMLElement) {
75
- this.target.setAttribute('tabindex', '-1')
76
- // 去掉节点被选中时container出现的边框
77
- this.target.style.outline = 'none'
78
- }
79
- }
80
- }
81
-
82
- disable() {
83
- if (!this.disabled) {
84
- if (this.options.keyboard) {
85
- this.options.keyboard.enabled = false
86
- }
87
- if (this.target instanceof HTMLElement) {
88
- this.target.removeAttribute('tabindex')
89
- }
90
- }
91
- }
92
-
93
- destroy() {
94
- this.mousetrap.reset()
95
- }
96
-
97
- private getKeys(keys: string | string[]) {
98
- return (Array.isArray(keys) ? keys : [keys]).map((key) =>
99
- this.formatKey(key),
100
- )
101
- }
102
-
103
- protected formatKey(key: string) {
104
- return key
105
- .toLowerCase()
106
- .replace(/\s/g, '')
107
- .replace('delete', 'del')
108
- .replace('cmd', 'command')
109
- }
110
- }
111
-
112
- export default Keyboard
@@ -1,200 +0,0 @@
1
- import { isEmpty } from 'lodash-es'
2
- import LogicFlow from '../LogicFlow'
3
- import { map } from 'lodash-es'
4
- import GraphModel from '../model/GraphModel'
5
-
6
- import NodeData = LogicFlow.NodeData
7
- import EdgeData = LogicFlow.EdgeData
8
- import NodeConfig = LogicFlow.NodeConfig
9
- import EdgeConfig = LogicFlow.EdgeConfig
10
-
11
- let selected: LogicFlow.GraphData | null = null
12
-
13
- export function translateNodeData(nodeData: NodeData, distance: number) {
14
- nodeData.x += distance
15
- nodeData.y += distance
16
-
17
- if (!isEmpty(nodeData.text)) {
18
- nodeData.text.x += distance
19
- nodeData.text.y += distance
20
- }
21
-
22
- if (!isEmpty(nodeData.properties?._label)) {
23
- nodeData.properties?._label.forEach((label) => {
24
- label.x += distance
25
- label.y += distance
26
- })
27
- }
28
- return nodeData
29
- }
30
-
31
- export function translateEdgeData(edgeData: EdgeData, distance: number) {
32
- if (edgeData.startPoint) {
33
- edgeData.startPoint.x += distance
34
- edgeData.startPoint.y += distance
35
- }
36
- if (edgeData.endPoint) {
37
- edgeData.endPoint.x += distance
38
- edgeData.endPoint.y += distance
39
- }
40
- if (edgeData.pointsList && edgeData.pointsList.length > 0) {
41
- edgeData.pointsList.forEach((point) => {
42
- point.x += distance
43
- point.y += distance
44
- })
45
- }
46
-
47
- if (!isEmpty(edgeData.text)) {
48
- edgeData.text.x += distance
49
- edgeData.text.y += distance
50
- }
51
- return edgeData
52
- }
53
-
54
- export function transformNodeData(
55
- nodeData: NodeData,
56
- distance: number,
57
- ): NodeConfig {
58
- const { x, y, text } = nodeData
59
- // 重新计算 text 的位置,保证粘贴后 text 位置和复制的原节点相对位置一致
60
- const nextText = text
61
- ? {
62
- x: text.x + distance,
63
- y: text.y + distance,
64
- value: text.value,
65
- }
66
- : undefined
67
-
68
- return {
69
- ...nodeData,
70
- id: '',
71
- x: x + distance,
72
- y: y + distance,
73
- text: nextText,
74
- }
75
- }
76
-
77
- export function transformEdgeData(
78
- edgeData: EdgeData,
79
- distance: number,
80
- ): EdgeConfig {
81
- const { startPoint, endPoint, pointsList, text, ...edgeConfig } = edgeData
82
- // 清除原始边的 id
83
- edgeConfig.id = ''
84
-
85
- // 重新计算边的位置,包括 startPoint、endPoint、pointsList 以及 text
86
- // TODO: 看这个是否可以提出一个通用方法,用于重新计算边的位置
87
- const nextStartPoint = {
88
- x: startPoint.x + distance,
89
- y: startPoint.y + distance,
90
- }
91
- const nextEndPoint = {
92
- x: endPoint.x + distance,
93
- y: endPoint.y + distance,
94
- }
95
- const newPointsList: LogicFlow.Point[] = map(pointsList, (point) => {
96
- return {
97
- x: point.x + distance,
98
- y: point.y + distance,
99
- }
100
- })
101
- const nextText = text
102
- ? {
103
- ...text,
104
- x: text.x + distance,
105
- y: text.y + distance,
106
- }
107
- : undefined
108
-
109
- return {
110
- ...edgeConfig,
111
- startPoint: nextStartPoint,
112
- endPoint: nextEndPoint,
113
- pointsList: newPointsList,
114
- text: nextText,
115
- }
116
- }
117
-
118
- const TRANSLATION_DISTANCE = 40
119
- let CHILDREN_TRANSLATION_DISTANCE = 40
120
-
121
- export function initDefaultShortcut(lf: LogicFlow, graph: GraphModel) {
122
- const { keyboard } = lf
123
- const {
124
- options: { keyboard: keyboardOptions },
125
- } = keyboard
126
-
127
- // 复制
128
- keyboard.on(['cmd + c', 'ctrl + c'], () => {
129
- CHILDREN_TRANSLATION_DISTANCE = TRANSLATION_DISTANCE
130
- if (!keyboardOptions?.enabled) return true
131
- if (graph.textEditElement) return true
132
- const { guards } = lf.options
133
- const elements = graph.getSelectElements(false)
134
- const enabledClone =
135
- guards && guards.beforeClone ? guards.beforeClone(elements) : true
136
- if (
137
- !enabledClone ||
138
- (elements.nodes.length === 0 && elements.edges.length === 0)
139
- ) {
140
- selected = null
141
- return true
142
- }
143
- selected = elements
144
- selected.nodes.forEach((node) =>
145
- translateNodeData(node, TRANSLATION_DISTANCE),
146
- )
147
- selected.edges.forEach((edge) =>
148
- translateEdgeData(edge, TRANSLATION_DISTANCE),
149
- )
150
- return false
151
- })
152
- // 粘贴
153
- keyboard.on(['cmd + v', 'ctrl + v'], () => {
154
- if (!keyboardOptions?.enabled) return true
155
- if (graph.textEditElement) return true
156
- if (selected && (selected.nodes || selected.edges)) {
157
- lf.clearSelectElements()
158
- const addElements = lf.addElements(
159
- selected,
160
- CHILDREN_TRANSLATION_DISTANCE,
161
- )
162
- if (!addElements) return true
163
- addElements.nodes.forEach((node) => lf.selectElementById(node.id, true))
164
- addElements.edges.forEach((edge) => lf.selectElementById(edge.id, true))
165
- selected.nodes.forEach((node) =>
166
- translateNodeData(node, TRANSLATION_DISTANCE),
167
- )
168
- selected.edges.forEach((edge) =>
169
- translateEdgeData(edge, TRANSLATION_DISTANCE),
170
- )
171
- CHILDREN_TRANSLATION_DISTANCE =
172
- CHILDREN_TRANSLATION_DISTANCE + TRANSLATION_DISTANCE
173
- }
174
- return false
175
- })
176
- // undo
177
- keyboard.on(['cmd + z', 'ctrl + z'], () => {
178
- if (!keyboardOptions?.enabled) return true
179
- if (graph.textEditElement) return true
180
- lf.undo()
181
- return false
182
- })
183
- // redo
184
- keyboard.on(['cmd + y', 'ctrl + y'], () => {
185
- if (!keyboardOptions?.enabled) return true
186
- if (graph.textEditElement) return true
187
- lf.redo()
188
- return false
189
- })
190
- // delete
191
- keyboard.on(['backspace'], () => {
192
- if (!keyboardOptions?.enabled) return true
193
- if (graph.textEditElement) return true
194
- const elements = graph.getSelectElements(true)
195
- lf.clearSelectElements()
196
- elements.edges.forEach((edge) => edge.id && lf.deleteEdge(edge.id))
197
- elements.nodes.forEach((node) => node.id && lf.deleteNode(node.id))
198
- return false
199
- })
200
- }