@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.
- package/package.json +6 -1
- package/.turbo/turbo-build$colon$dev.log +0 -10
- package/.turbo/turbo-build.log +0 -33
- package/CHANGELOG.md +0 -1901
- package/__tests__/algorithm/egde.test.ts +0 -131
- package/__tests__/algorithm/index.test.ts +0 -74
- package/__tests__/algorithm/outline.test.ts +0 -43
- package/__tests__/bugs/1545-spec.test.ts +0 -42
- package/__tests__/event/event.test.ts +0 -22
- package/__tests__/history/history.test.ts +0 -28
- package/__tests__/logicflow.test.ts +0 -575
- package/__tests__/model/graphmodel.test.ts +0 -87
- package/__tests__/util/compatible.test.ts +0 -48
- package/__tests__/util/edge.test.ts +0 -224
- package/__tests__/util/geometry.test.ts +0 -14
- package/__tests__/util/graph.test.ts +0 -16
- package/__tests__/util/matrix.test.ts +0 -41
- package/__tests__/util/node.test.ts +0 -68
- package/__tests__/util/sampling.test.ts +0 -12
- package/__tests__/util/vector.test.ts +0 -50
- package/__tests__/util/zIndex.test.ts +0 -10
- package/src/LogicFlow.tsx +0 -2017
- package/src/algorithm/edge.ts +0 -67
- package/src/algorithm/index.ts +0 -70
- package/src/algorithm/outline.ts +0 -77
- package/src/algorithm/rotate.ts +0 -55
- package/src/common/drag.ts +0 -219
- package/src/common/history.ts +0 -108
- package/src/common/index.ts +0 -6
- package/src/common/keyboard.ts +0 -108
- package/src/common/matrix.ts +0 -122
- package/src/common/vector.ts +0 -93
- package/src/constant/index.ts +0 -179
- package/src/constant/theme.ts +0 -708
- package/src/event/event.md +0 -66
- package/src/event/eventArgs.ts +0 -643
- package/src/event/eventEmitter.ts +0 -156
- package/src/history/index.ts +0 -119
- package/src/index.less +0 -1
- package/src/index.ts +0 -26
- package/src/keyboard/index.ts +0 -112
- package/src/keyboard/shortcut.ts +0 -200
- package/src/model/BaseModel.ts +0 -250
- package/src/model/EditConfigModel.ts +0 -334
- package/src/model/GraphModel.ts +0 -1824
- package/src/model/NestedTransformModel.ts +0 -121
- package/src/model/SnaplineModel.ts +0 -256
- package/src/model/TransformModel.ts +0 -258
- package/src/model/edge/BaseEdgeModel.ts +0 -785
- package/src/model/edge/BezierEdgeModel.ts +0 -197
- package/src/model/edge/LineEdgeModel.ts +0 -36
- package/src/model/edge/PolylineEdgeModel.ts +0 -817
- package/src/model/edge/index.ts +0 -4
- package/src/model/index.ts +0 -9
- package/src/model/node/BaseNodeModel.ts +0 -959
- package/src/model/node/CircleNodeModel.ts +0 -91
- package/src/model/node/DiamondNodeModel.ts +0 -132
- package/src/model/node/EllipseNodeModel.ts +0 -98
- package/src/model/node/HtmlNodeModel.ts +0 -64
- package/src/model/node/PolygonNodeModel.ts +0 -152
- package/src/model/node/RectNodeModel.ts +0 -69
- package/src/model/node/TextNodeModel.ts +0 -54
- package/src/model/node/index.ts +0 -8
- package/src/options.ts +0 -150
- package/src/style/index.less +0 -262
- package/src/style/raw.ts +0 -221
- package/src/tool/MultipleSelectTool.tsx +0 -140
- package/src/tool/TextEditTool.tsx +0 -193
- package/src/tool/index.ts +0 -101
- package/src/typings.d.ts +0 -5
- package/src/util/animation.ts +0 -29
- package/src/util/browser.ts +0 -4
- package/src/util/compatible.ts +0 -15
- package/src/util/drag.ts +0 -219
- package/src/util/edge.ts +0 -1094
- package/src/util/geometry.ts +0 -154
- package/src/util/graph.ts +0 -46
- package/src/util/index.ts +0 -17
- package/src/util/matrix.ts +0 -129
- package/src/util/mobx.ts +0 -23
- package/src/util/node.ts +0 -543
- package/src/util/raf.ts +0 -28
- package/src/util/resize.ts +0 -606
- package/src/util/sampling.ts +0 -85
- package/src/util/theme.ts +0 -84
- package/src/util/uuid.ts +0 -26
- package/src/util/vector.ts +0 -93
- package/src/util/zIndex.ts +0 -6
- package/src/view/Anchor.tsx +0 -462
- package/src/view/Control.tsx +0 -510
- package/src/view/Graph.tsx +0 -141
- package/src/view/Rotate.tsx +0 -113
- package/src/view/behavior/dnd.ts +0 -162
- package/src/view/behavior/index.ts +0 -2
- package/src/view/behavior/snapline.ts +0 -16
- package/src/view/edge/AdjustPoint.tsx +0 -425
- package/src/view/edge/Arrow.tsx +0 -54
- package/src/view/edge/BaseEdge.tsx +0 -660
- package/src/view/edge/BezierEdge.tsx +0 -101
- package/src/view/edge/LineEdge.tsx +0 -81
- package/src/view/edge/PolylineEdge.tsx +0 -311
- package/src/view/edge/index.ts +0 -6
- package/src/view/index.ts +0 -8
- package/src/view/node/BaseNode.tsx +0 -585
- package/src/view/node/CircleNode.tsx +0 -21
- package/src/view/node/DiamondNode.tsx +0 -24
- package/src/view/node/EllipseNode.tsx +0 -22
- package/src/view/node/HtmlNode.tsx +0 -112
- package/src/view/node/PolygonNode.tsx +0 -28
- package/src/view/node/RectNode.tsx +0 -30
- package/src/view/node/TextNode.tsx +0 -39
- package/src/view/node/index.ts +0 -8
- package/src/view/overlay/BackgroundOverlay.tsx +0 -34
- package/src/view/overlay/BezierAdjustOverlay.tsx +0 -150
- package/src/view/overlay/CanvasOverlay.tsx +0 -290
- package/src/view/overlay/Grid.tsx +0 -319
- package/src/view/overlay/ModificationOverlay.tsx +0 -31
- package/src/view/overlay/OutlineOverlay.tsx +0 -158
- package/src/view/overlay/SnaplineOverlay.tsx +0 -44
- package/src/view/overlay/ToolOverlay.tsx +0 -65
- package/src/view/overlay/getTransformHoc.tsx +0 -50
- package/src/view/overlay/gridConfig.ts +0 -103
- package/src/view/overlay/index.ts +0 -8
- package/src/view/shape/Circle.tsx +0 -41
- package/src/view/shape/Ellipse.tsx +0 -42
- package/src/view/shape/Line.tsx +0 -39
- package/src/view/shape/Path.tsx +0 -22
- package/src/view/shape/Polygon.tsx +0 -54
- package/src/view/shape/Polyline.tsx +0 -31
- package/src/view/shape/Rect.tsx +0 -44
- package/src/view/shape/Text.tsx +0 -168
- package/src/view/shape/index.ts +0 -8
- package/src/view/text/BaseText.tsx +0 -134
- package/src/view/text/LineText.tsx +0 -168
- package/src/view/text/index.ts +0 -2
- package/stats.html +0 -4842
- package/tsconfig.json +0 -18
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { createRef } from 'preact/compat'
|
|
2
|
-
import BaseNode from './BaseNode'
|
|
3
|
-
import { GraphModel, HtmlNodeModel } from '../../model'
|
|
4
|
-
|
|
5
|
-
export type IHtmlNodeProps = {
|
|
6
|
-
model: HtmlNodeModel
|
|
7
|
-
graphModel: GraphModel
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export class HtmlNode<
|
|
11
|
-
P extends IHtmlNodeProps = IHtmlNodeProps,
|
|
12
|
-
> extends BaseNode<P> {
|
|
13
|
-
ref = createRef()
|
|
14
|
-
currentProperties?: string
|
|
15
|
-
preProperties?: string
|
|
16
|
-
|
|
17
|
-
get rootEl() {
|
|
18
|
-
return this.ref.current
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @overridable 支持重写
|
|
23
|
-
* 自定义HTML节点内容
|
|
24
|
-
* @param {HTMLElement} rootEl 自定义HTML节点内容可以挂载的dom节点
|
|
25
|
-
* @example
|
|
26
|
-
* class CustomHtmlNode extends HtmlNode {
|
|
27
|
-
* setHtml(rootEl) {
|
|
28
|
-
* const input = document.createElement('input');
|
|
29
|
-
* rootEl.appendChild(input)
|
|
30
|
-
* }
|
|
31
|
-
* }
|
|
32
|
-
*/
|
|
33
|
-
setHtml(rootEl: SVGForeignObjectElement) {
|
|
34
|
-
rootEl.appendChild(document.createElement('div'))
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// TODO: 1. 应该在什么时机进行更新呢?2. 如何精细化控制
|
|
38
|
-
confirmUpdate(rootEl: SVGForeignObjectElement) {
|
|
39
|
-
this.setHtml(rootEl)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @overridable 支持重写
|
|
44
|
-
* 和react的shouldComponentUpdate类似,都是为了避免出发不必要的render.
|
|
45
|
-
* 但是这里不一样的地方在于,setHtml方法,我们只在properties发生变化了后再触发。
|
|
46
|
-
* 而x,y等这些坐标相关的方法发生了变化,不会再重新触发setHtml.
|
|
47
|
-
*/
|
|
48
|
-
shouldUpdate() {
|
|
49
|
-
if (this.preProperties && this.preProperties === this.currentProperties) {
|
|
50
|
-
return false
|
|
51
|
-
}
|
|
52
|
-
this.preProperties = this.currentProperties
|
|
53
|
-
return true
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
componentDidMount() {
|
|
57
|
-
if (this.shouldUpdate() && this.rootEl) {
|
|
58
|
-
this.setHtml(this.rootEl)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
componentDidUpdate() {
|
|
63
|
-
// DONE: 将 componentDidMount 和 componentDidUpdate 区分开,如果写在一次,渲染 React 组件会重复初始化,消耗过多资源
|
|
64
|
-
// 为了保证历史兼容性,先将默认 HTML 节点的 setHtml 和 confirmUpdate 保持一直,用户可通过自定义的方式重新定义
|
|
65
|
-
if (this.shouldUpdate() && this.rootEl) {
|
|
66
|
-
this.confirmUpdate(this.rootEl)
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
componentWillUnmount() {
|
|
71
|
-
super.componentWillUnmount()
|
|
72
|
-
this.rootEl.innerHTML = ''
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
getShape() {
|
|
76
|
-
const { model } = this.props
|
|
77
|
-
const { x, y, height, width } = model
|
|
78
|
-
const style = model.getNodeStyle()
|
|
79
|
-
this.currentProperties = JSON.stringify(model.properties)
|
|
80
|
-
return (
|
|
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>
|
|
108
|
-
)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export default HtmlNode
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import BaseNode from './BaseNode'
|
|
2
|
-
import { Polygon } from '../shape'
|
|
3
|
-
import { GraphModel, PolygonNodeModel } from '../../model'
|
|
4
|
-
|
|
5
|
-
export type IPolygonNodeProps = {
|
|
6
|
-
model: PolygonNodeModel
|
|
7
|
-
graphModel: GraphModel
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export class PolygonNode<
|
|
11
|
-
P extends IPolygonNodeProps = IPolygonNodeProps,
|
|
12
|
-
> extends BaseNode<P> {
|
|
13
|
-
getShape() {
|
|
14
|
-
const { model } = this.props
|
|
15
|
-
const { x, y, width, height, points } = model as PolygonNodeModel
|
|
16
|
-
const style = model.getNodeStyle()
|
|
17
|
-
const attr = {
|
|
18
|
-
transform: `matrix(1 0 0 1 ${x - width / 2} ${y - height / 2})`,
|
|
19
|
-
}
|
|
20
|
-
return (
|
|
21
|
-
<g {...attr}>
|
|
22
|
-
<Polygon {...style} points={points} x={x} y={y} />
|
|
23
|
-
</g>
|
|
24
|
-
)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export default PolygonNode
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { createElement as h } from 'preact/compat'
|
|
2
|
-
import BaseNode from './BaseNode'
|
|
3
|
-
import { Rect } from '../shape'
|
|
4
|
-
import { GraphModel, RectNodeModel } from '../../model'
|
|
5
|
-
|
|
6
|
-
export type IRectNodeProps = {
|
|
7
|
-
model: RectNodeModel
|
|
8
|
-
graphModel: GraphModel
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class RectNode<
|
|
12
|
-
P extends IRectNodeProps = IRectNodeProps,
|
|
13
|
-
> extends BaseNode<P> {
|
|
14
|
-
getShape(): h.JSX.Element | null {
|
|
15
|
-
const { model } = this.props
|
|
16
|
-
const style = model.getNodeStyle()
|
|
17
|
-
return (
|
|
18
|
-
<Rect
|
|
19
|
-
{...style}
|
|
20
|
-
x={model.x}
|
|
21
|
-
y={model.y}
|
|
22
|
-
width={model.width}
|
|
23
|
-
height={model.height}
|
|
24
|
-
radius={model.radius}
|
|
25
|
-
/>
|
|
26
|
-
)
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export default RectNode
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import Rect from '../shape/Rect'
|
|
2
|
-
import BaseNode from './BaseNode'
|
|
3
|
-
import { GraphModel, TextNodeModel } from '../../model'
|
|
4
|
-
|
|
5
|
-
export type ITextNodeProps = {
|
|
6
|
-
model: TextNodeModel
|
|
7
|
-
graphModel: GraphModel
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export class TextNode<
|
|
11
|
-
P extends ITextNodeProps = ITextNodeProps,
|
|
12
|
-
> extends BaseNode<P> {
|
|
13
|
-
getBackground() {
|
|
14
|
-
const { model } = this.props
|
|
15
|
-
const style = model.getTextStyle()
|
|
16
|
-
// 背景框宽度,最长一行字节数/2 * fontsize + 2
|
|
17
|
-
// 背景框宽度, 行数 * fontsize + 2
|
|
18
|
-
// FIX: #1067
|
|
19
|
-
const { width, height, x, y } = model
|
|
20
|
-
const rectAttr = {
|
|
21
|
-
...style.background,
|
|
22
|
-
x,
|
|
23
|
-
y,
|
|
24
|
-
width,
|
|
25
|
-
height,
|
|
26
|
-
}
|
|
27
|
-
return <Rect {...rectAttr} />
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
getResizeControl() {
|
|
31
|
-
return null
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
getShape() {
|
|
35
|
-
return <g>{this.getBackground()}</g>
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export default TextNode
|
package/src/view/node/index.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { Component } from 'preact/compat'
|
|
2
|
-
import { isObject } from 'lodash-es'
|
|
3
|
-
import { Options as LFOptions } from '../../options'
|
|
4
|
-
import { observer } from '../..'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 背景配置, 支持css属性配置
|
|
8
|
-
* https://developer.mozilla.org/zh-CN/docs/Web/CSS/background
|
|
9
|
-
* @example
|
|
10
|
-
* {
|
|
11
|
-
* backgroundImage: "url('./img/grid.svg')",
|
|
12
|
-
backgroundRepeat: 'repeat',
|
|
13
|
-
* }
|
|
14
|
-
*/
|
|
15
|
-
type IProps = {
|
|
16
|
-
background: boolean | LFOptions.BackgroundConfig
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
@observer
|
|
20
|
-
export class BackgroundOverlay extends Component<IProps> {
|
|
21
|
-
render() {
|
|
22
|
-
const { background } = this.props
|
|
23
|
-
return (
|
|
24
|
-
<div className="lf-background">
|
|
25
|
-
<div
|
|
26
|
-
style={isObject(background) ? background : {}}
|
|
27
|
-
className="lf-background-area"
|
|
28
|
-
/>
|
|
29
|
-
</div>
|
|
30
|
-
)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export default BackgroundOverlay
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { Component } from 'preact/compat'
|
|
2
|
-
import { Circle, Line } from '../shape'
|
|
3
|
-
import { observer } from '../..'
|
|
4
|
-
import LogicFlow from '../../LogicFlow'
|
|
5
|
-
import { EventType, ModelType } from '../../constant'
|
|
6
|
-
import { StepDrag, getBezierPoints, IDragParams } from '../../util'
|
|
7
|
-
import { GraphModel, BezierEdgeModel } from '../../model'
|
|
8
|
-
|
|
9
|
-
import Point = LogicFlow.Point
|
|
10
|
-
|
|
11
|
-
type IProps = {
|
|
12
|
-
graphModel: GraphModel
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
type IAnchorProps = {
|
|
16
|
-
position: Point
|
|
17
|
-
bezierModel: BezierEdgeModel
|
|
18
|
-
graphModel: GraphModel
|
|
19
|
-
type: string
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
type IState = {
|
|
23
|
-
endX: number
|
|
24
|
-
endY: number
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// bezier曲线的可调整锚点
|
|
28
|
-
export class BezierAdjustAnchor extends Component<IAnchorProps, IState> {
|
|
29
|
-
dragHandler: StepDrag
|
|
30
|
-
|
|
31
|
-
constructor() {
|
|
32
|
-
super()
|
|
33
|
-
this.dragHandler = new StepDrag({
|
|
34
|
-
onDragging: this.onDragging,
|
|
35
|
-
onDragEnd: this.onDragEnd,
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
onDragging = ({ event }: IDragParams) => {
|
|
40
|
-
const { graphModel, bezierModel, type } = this.props
|
|
41
|
-
const {
|
|
42
|
-
canvasOverlayPosition: { x, y },
|
|
43
|
-
} = graphModel.getPointByClient({
|
|
44
|
-
x: event!.clientX,
|
|
45
|
-
y: event!.clientY,
|
|
46
|
-
})
|
|
47
|
-
bezierModel.updateAdjustAnchor(
|
|
48
|
-
{
|
|
49
|
-
x,
|
|
50
|
-
y,
|
|
51
|
-
},
|
|
52
|
-
type,
|
|
53
|
-
)
|
|
54
|
-
graphModel.eventCenter.emit(EventType.EDGE_ADJUST, {
|
|
55
|
-
data: bezierModel.getData(),
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
onDragEnd = () => {
|
|
59
|
-
const { bezierModel } = this.props
|
|
60
|
-
bezierModel.isDragging = false
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
render() {
|
|
64
|
-
const { position } = this.props
|
|
65
|
-
const { x, y } = position
|
|
66
|
-
const { bezierModel } = this.props
|
|
67
|
-
const { adjustAnchor } = bezierModel.getEdgeStyle()
|
|
68
|
-
return (
|
|
69
|
-
<Circle
|
|
70
|
-
className="lf-bezier-adjust-anchor"
|
|
71
|
-
x={x}
|
|
72
|
-
y={y}
|
|
73
|
-
{...adjustAnchor}
|
|
74
|
-
onPointerDown={(ev) => {
|
|
75
|
-
// if (edgeAddable !== false) {
|
|
76
|
-
this.dragHandler.handleMouseDown(ev)
|
|
77
|
-
// }
|
|
78
|
-
}}
|
|
79
|
-
/>
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
@observer
|
|
85
|
-
export class BezierAdjustOverlay extends Component<IProps> {
|
|
86
|
-
getBezierAdjust(bezier: BezierEdgeModel, graphModel: GraphModel) {
|
|
87
|
-
const { path, id } = bezier
|
|
88
|
-
const pointsList = getBezierPoints(path)
|
|
89
|
-
const [start, sNext, ePre, end] = pointsList
|
|
90
|
-
const { adjustLine } = bezier.getEdgeStyle()
|
|
91
|
-
const result: any = [] // TODO: 类型定义
|
|
92
|
-
result.push(
|
|
93
|
-
<Line
|
|
94
|
-
x1={start.x}
|
|
95
|
-
y1={start.y}
|
|
96
|
-
x2={sNext.x}
|
|
97
|
-
y2={sNext.y}
|
|
98
|
-
{...adjustLine}
|
|
99
|
-
/>,
|
|
100
|
-
)
|
|
101
|
-
result.push(
|
|
102
|
-
<BezierAdjustAnchor
|
|
103
|
-
position={sNext}
|
|
104
|
-
bezierModel={bezier}
|
|
105
|
-
graphModel={graphModel}
|
|
106
|
-
key={`${id}_ePre`}
|
|
107
|
-
type="sNext"
|
|
108
|
-
/>,
|
|
109
|
-
)
|
|
110
|
-
result.push(
|
|
111
|
-
<Line x1={end.x} y1={end.y} x2={ePre.x} y2={ePre.y} {...adjustLine} />,
|
|
112
|
-
)
|
|
113
|
-
result.push(
|
|
114
|
-
<BezierAdjustAnchor
|
|
115
|
-
position={ePre}
|
|
116
|
-
bezierModel={bezier}
|
|
117
|
-
graphModel={graphModel}
|
|
118
|
-
key={`${id}_sNext`}
|
|
119
|
-
type="ePre"
|
|
120
|
-
/>,
|
|
121
|
-
)
|
|
122
|
-
return result
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// 获取选中bezier曲线,调整操作线和锚点
|
|
126
|
-
selectedBezierEdge() {
|
|
127
|
-
const { graphModel } = this.props
|
|
128
|
-
const edgeList = graphModel.edges
|
|
129
|
-
const edgeAdjust: any = [] // TODO:类型定义
|
|
130
|
-
for (let i = 0; i < edgeList.length; i++) {
|
|
131
|
-
const edge = edgeList[i]
|
|
132
|
-
if (
|
|
133
|
-
edge.isSelected &&
|
|
134
|
-
edge.modelType === ModelType.BEZIER_EDGE &&
|
|
135
|
-
edge.draggable
|
|
136
|
-
) {
|
|
137
|
-
edgeAdjust.push(
|
|
138
|
-
this.getBezierAdjust(edge as BezierEdgeModel, graphModel),
|
|
139
|
-
)
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return edgeAdjust
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
render() {
|
|
146
|
-
return <g className="lf-bezier-adjust">{this.selectedBezierEdge()}</g>
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export default BezierAdjustOverlay
|
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
import { Component } from 'preact/compat'
|
|
2
|
-
import Dnd from '../behavior/dnd'
|
|
3
|
-
import { observer } from '../..'
|
|
4
|
-
import GraphModel from '../../model/GraphModel'
|
|
5
|
-
import { EventType } from '../../constant'
|
|
6
|
-
import { StepDrag, IDragParams } from '../../util'
|
|
7
|
-
|
|
8
|
-
type IProps = {
|
|
9
|
-
graphModel: GraphModel
|
|
10
|
-
dnd: Dnd
|
|
11
|
-
}
|
|
12
|
-
type IState = {
|
|
13
|
-
isDragging: boolean
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
@observer
|
|
17
|
-
export class CanvasOverlay extends Component<IProps, IState> {
|
|
18
|
-
stepDrag: StepDrag
|
|
19
|
-
stepScrollX = 0
|
|
20
|
-
stepScrollY = 0
|
|
21
|
-
pointers = new Map<number, { x: number; y: number }>()
|
|
22
|
-
pinchStartDistance?: number
|
|
23
|
-
pinchStartScale?: number
|
|
24
|
-
pinchLastCenterX?: number
|
|
25
|
-
pinchLastCenterY?: number
|
|
26
|
-
longPressTimer?: number
|
|
27
|
-
|
|
28
|
-
constructor(props: IProps) {
|
|
29
|
-
super()
|
|
30
|
-
const {
|
|
31
|
-
graphModel: { gridSize, eventCenter },
|
|
32
|
-
} = props
|
|
33
|
-
this.stepDrag = new StepDrag({
|
|
34
|
-
onDragging: this.onDragging,
|
|
35
|
-
onDragEnd: this.onDragEnd,
|
|
36
|
-
step: gridSize,
|
|
37
|
-
eventType: 'BLANK',
|
|
38
|
-
isStopPropagation: false,
|
|
39
|
-
eventCenter,
|
|
40
|
-
model: undefined,
|
|
41
|
-
})
|
|
42
|
-
// 当 ctrl、cmd 键被按住的时候,可以放大缩小。
|
|
43
|
-
this.state = {
|
|
44
|
-
isDragging: false,
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// get InjectedProps() {
|
|
49
|
-
// return this.props as InjectedProps;
|
|
50
|
-
// }
|
|
51
|
-
onDragging = ({ deltaX, deltaY }: IDragParams) => {
|
|
52
|
-
if (this.longPressTimer) {
|
|
53
|
-
clearTimeout(this.longPressTimer)
|
|
54
|
-
this.longPressTimer = undefined
|
|
55
|
-
}
|
|
56
|
-
this.setState({
|
|
57
|
-
isDragging: true,
|
|
58
|
-
})
|
|
59
|
-
const {
|
|
60
|
-
graphModel: { transformModel, editConfigModel },
|
|
61
|
-
} = this.props
|
|
62
|
-
if (editConfigModel.stopMoveGraph === true) {
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
transformModel.translate(deltaX, deltaY)
|
|
66
|
-
}
|
|
67
|
-
onDragEnd = () => {
|
|
68
|
-
this.setState({
|
|
69
|
-
isDragging: false,
|
|
70
|
-
})
|
|
71
|
-
}
|
|
72
|
-
zoomHandler = (ev: WheelEvent) => {
|
|
73
|
-
const {
|
|
74
|
-
graphModel: { editConfigModel, transformModel, gridSize },
|
|
75
|
-
graphModel,
|
|
76
|
-
} = this.props
|
|
77
|
-
const { deltaX: eX, deltaY: eY } = ev
|
|
78
|
-
const { stopScrollGraph, stopZoomGraph } = editConfigModel
|
|
79
|
-
// 如果没有禁止滚动移动画布, 并且当前触发的时候ctrl键、cmd键没有按住, 那么移动画布
|
|
80
|
-
if (!stopScrollGraph && !ev.ctrlKey && !ev.metaKey) {
|
|
81
|
-
ev.preventDefault()
|
|
82
|
-
this.stepScrollX += eX
|
|
83
|
-
this.stepScrollY += eY
|
|
84
|
-
if (Math.abs(this.stepScrollX) >= gridSize) {
|
|
85
|
-
const remainderX = this.stepScrollX % gridSize
|
|
86
|
-
const moveDistance = this.stepScrollX - remainderX
|
|
87
|
-
transformModel.translate(-moveDistance * transformModel.SCALE_X, 0)
|
|
88
|
-
this.stepScrollX = remainderX
|
|
89
|
-
}
|
|
90
|
-
if (Math.abs(this.stepScrollY) >= gridSize) {
|
|
91
|
-
const remainderY = this.stepScrollY % gridSize
|
|
92
|
-
const moveDistanceY = this.stepScrollY - remainderY
|
|
93
|
-
transformModel.translate(0, -moveDistanceY * transformModel.SCALE_Y)
|
|
94
|
-
this.stepScrollY = remainderY
|
|
95
|
-
}
|
|
96
|
-
return
|
|
97
|
-
}
|
|
98
|
-
// 如果没有禁止缩放画布,那么进行缩放. 在禁止缩放画布后,按住 ctrl、cmd 键也不能缩放了。
|
|
99
|
-
if (!stopZoomGraph) {
|
|
100
|
-
ev.preventDefault()
|
|
101
|
-
const position = graphModel.getPointByClient({
|
|
102
|
-
x: ev.clientX,
|
|
103
|
-
y: ev.clientY,
|
|
104
|
-
})
|
|
105
|
-
const { x, y } = position.canvasOverlayPosition
|
|
106
|
-
transformModel.zoom(ev.deltaY < 0, [x, y])
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
clickHandler = (ev: MouseEvent) => {
|
|
110
|
-
// 点击空白处取消节点选中状态, 不包括冒泡过来的事件。
|
|
111
|
-
const target = ev.target as HTMLElement
|
|
112
|
-
if (target.getAttribute('name') === 'canvas-overlay') {
|
|
113
|
-
const { graphModel } = this.props
|
|
114
|
-
const { selectElements } = graphModel
|
|
115
|
-
if (selectElements.size > 0) {
|
|
116
|
-
graphModel.clearSelectElements()
|
|
117
|
-
}
|
|
118
|
-
// 如果是拖拽状态,不触发点击事件
|
|
119
|
-
if (this.state.isDragging) return
|
|
120
|
-
graphModel.eventCenter.emit(EventType.BLANK_CLICK, { e: ev })
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
handleContextMenu = (ev: MouseEvent) => {
|
|
124
|
-
const target = ev.target as HTMLElement
|
|
125
|
-
if (target.getAttribute('name') === 'canvas-overlay') {
|
|
126
|
-
ev.preventDefault()
|
|
127
|
-
const { graphModel } = this.props
|
|
128
|
-
const position = graphModel.getPointByClient({
|
|
129
|
-
x: ev.clientX,
|
|
130
|
-
y: ev.clientY,
|
|
131
|
-
})
|
|
132
|
-
// graphModel.setElementState(ElementState.SHOW_MENU, position.domOverlayPosition);
|
|
133
|
-
graphModel.eventCenter.emit(EventType.BLANK_CONTEXTMENU, {
|
|
134
|
-
e: ev,
|
|
135
|
-
position,
|
|
136
|
-
})
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// 鼠标、触摸板 按下
|
|
140
|
-
pointerDownHandler = (ev: PointerEvent) => {
|
|
141
|
-
const {
|
|
142
|
-
graphModel: {
|
|
143
|
-
eventCenter,
|
|
144
|
-
editConfigModel,
|
|
145
|
-
transformModel: { SCALE_X },
|
|
146
|
-
gridSize,
|
|
147
|
-
},
|
|
148
|
-
} = this.props
|
|
149
|
-
this.pointers.set(ev.pointerId, { x: ev.clientX, y: ev.clientY })
|
|
150
|
-
if (this.longPressTimer) {
|
|
151
|
-
clearTimeout(this.longPressTimer)
|
|
152
|
-
}
|
|
153
|
-
if (ev.pointerType === 'touch') {
|
|
154
|
-
this.longPressTimer = window.setTimeout(() => {
|
|
155
|
-
this.handleContextMenu(ev)
|
|
156
|
-
}, 500)
|
|
157
|
-
}
|
|
158
|
-
// 检测双指触摸,初始化捏合缩放
|
|
159
|
-
if (this.pointers.size === 2) {
|
|
160
|
-
const {
|
|
161
|
-
graphModel: { transformModel, editConfigModel },
|
|
162
|
-
} = this.props
|
|
163
|
-
// 记录两指当前位置用于计算初始距离
|
|
164
|
-
const pts = Array.from(this.pointers.values())
|
|
165
|
-
const dx = pts[0].x - pts[1].x
|
|
166
|
-
const dy = pts[0].y - pts[1].y
|
|
167
|
-
const cx = (pts[0].x + pts[1].x) / 2
|
|
168
|
-
const cy = (pts[0].y + pts[1].y) / 2
|
|
169
|
-
// 记录捏合起始距离与当前缩放,后续按比例计算缩放
|
|
170
|
-
this.pinchStartDistance = Math.hypot(dx, dy)
|
|
171
|
-
this.pinchStartScale = transformModel.SCALE_X
|
|
172
|
-
// 双指操作下取消画布拖拽,避免与捏合缩放冲突
|
|
173
|
-
this.stepDrag.cancelDrag()
|
|
174
|
-
this.pinchLastCenterX = cx
|
|
175
|
-
this.pinchLastCenterY = cy
|
|
176
|
-
editConfigModel.updateEditConfig({ isPinching: true })
|
|
177
|
-
return
|
|
178
|
-
}
|
|
179
|
-
const { adjustEdge, adjustNodePosition, stopMoveGraph } = editConfigModel
|
|
180
|
-
const target = ev.target as HTMLElement
|
|
181
|
-
const isFrozenElement = !adjustEdge && !adjustNodePosition
|
|
182
|
-
if (target.getAttribute('name') === 'canvas-overlay' || isFrozenElement) {
|
|
183
|
-
if (stopMoveGraph !== true) {
|
|
184
|
-
this.stepDrag.setStep(gridSize * SCALE_X)
|
|
185
|
-
this.stepDrag.handleMouseDown(ev)
|
|
186
|
-
} else {
|
|
187
|
-
eventCenter.emit(EventType.BLANK_MOUSEDOWN, { e: ev })
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
pointerMoveHandler = (ev: PointerEvent) => {
|
|
192
|
-
// 记录当前指针位置(按 pointerId)
|
|
193
|
-
this.pointers.set(ev.pointerId, { x: ev.clientX, y: ev.clientY })
|
|
194
|
-
// 当已记录初始捏合距离且存在两指时,执行捏合缩放
|
|
195
|
-
if (this.pinchStartDistance && this.pointers.size >= 2) {
|
|
196
|
-
const {
|
|
197
|
-
graphModel,
|
|
198
|
-
graphModel: { editConfigModel, transformModel },
|
|
199
|
-
} = this.props
|
|
200
|
-
if (editConfigModel.stopZoomGraph) return
|
|
201
|
-
// 取消触摸长按计时,避免捏合过程中误触发上下文菜单
|
|
202
|
-
if (this.longPressTimer) {
|
|
203
|
-
clearTimeout(this.longPressTimer)
|
|
204
|
-
}
|
|
205
|
-
// 计算两指间当前距离
|
|
206
|
-
const pts = Array.from(this.pointers.values())
|
|
207
|
-
const dx = pts[0].x - pts[1].x
|
|
208
|
-
const dy = pts[0].y - pts[1].y
|
|
209
|
-
const dist = Math.hypot(dx, dy)
|
|
210
|
-
// 以初始缩放为基准,根据距离比例得到新的缩放比例
|
|
211
|
-
const scale =
|
|
212
|
-
(this.pinchStartScale ?? transformModel.SCALE_X) *
|
|
213
|
-
(dist / this.pinchStartDistance)
|
|
214
|
-
// 取两指中心作为缩放原点,并转换为画布坐标系
|
|
215
|
-
const cx = (pts[0].x + pts[1].x) / 2
|
|
216
|
-
const cy = (pts[0].y + pts[1].y) / 2
|
|
217
|
-
const pos = graphModel.getPointByClient({ x: cx, y: cy })
|
|
218
|
-
const { x, y } = pos.canvasOverlayPosition
|
|
219
|
-
transformModel.zoom(scale, [x, y])
|
|
220
|
-
// 双指中心位移驱动画布平移,配合缩放实现捏合移动;
|
|
221
|
-
if (!editConfigModel.stopMoveGraph || editConfigModel.isPinching) {
|
|
222
|
-
const deltaX =
|
|
223
|
-
this.pinchLastCenterX === undefined ? 0 : cx - this.pinchLastCenterX
|
|
224
|
-
const deltaY =
|
|
225
|
-
this.pinchLastCenterY === undefined ? 0 : cy - this.pinchLastCenterY
|
|
226
|
-
transformModel.translate(deltaX, deltaY)
|
|
227
|
-
this.pinchLastCenterX = cx
|
|
228
|
-
this.pinchLastCenterY = cy
|
|
229
|
-
}
|
|
230
|
-
ev.preventDefault()
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
pointerUpHandler = (ev: PointerEvent) => {
|
|
234
|
-
this.pointers.delete(ev.pointerId)
|
|
235
|
-
if (this.longPressTimer) {
|
|
236
|
-
clearTimeout(this.longPressTimer)
|
|
237
|
-
this.longPressTimer = undefined
|
|
238
|
-
}
|
|
239
|
-
// 双指松开或仅剩一指:结束捏合手势并清理临时状态
|
|
240
|
-
if (this.pointers.size < 2) {
|
|
241
|
-
// 清空捏合距离与缩放起始值
|
|
242
|
-
this.pinchStartDistance = undefined
|
|
243
|
-
this.pinchStartScale = undefined
|
|
244
|
-
// 清空上一帧的双指中心
|
|
245
|
-
this.pinchLastCenterX = undefined
|
|
246
|
-
this.pinchLastCenterY = undefined
|
|
247
|
-
const {
|
|
248
|
-
graphModel: { editConfigModel },
|
|
249
|
-
} = this.props
|
|
250
|
-
// 标记退出捏合,框选等交互可恢复
|
|
251
|
-
editConfigModel.updateEditConfig({ isPinching: false })
|
|
252
|
-
// 为了处理画布移动的时候,编辑和菜单仍然存在的问题。
|
|
253
|
-
this.clickHandler(ev)
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
render() {
|
|
258
|
-
const {
|
|
259
|
-
graphModel: { transformModel },
|
|
260
|
-
} = this.props
|
|
261
|
-
const { transform } = transformModel.getTransformStyle()
|
|
262
|
-
const { children } = this.props
|
|
263
|
-
const { isDragging } = this.state
|
|
264
|
-
|
|
265
|
-
return (
|
|
266
|
-
<svg
|
|
267
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
268
|
-
width="100%"
|
|
269
|
-
height="100%"
|
|
270
|
-
name="canvas-overlay"
|
|
271
|
-
onWheel={this.zoomHandler}
|
|
272
|
-
onPointerDown={this.pointerDownHandler}
|
|
273
|
-
onPointerMove={this.pointerMoveHandler}
|
|
274
|
-
onPointerUp={this.pointerUpHandler}
|
|
275
|
-
onPointerCancel={this.pointerUpHandler}
|
|
276
|
-
onContextMenu={this.handleContextMenu}
|
|
277
|
-
style={{ touchAction: 'none', WebkitUserSelect: 'none' }}
|
|
278
|
-
className={
|
|
279
|
-
isDragging
|
|
280
|
-
? 'lf-canvas-overlay lf-dragging'
|
|
281
|
-
: 'lf-canvas-overlay lf-drag-able'
|
|
282
|
-
}
|
|
283
|
-
>
|
|
284
|
-
<g transform={transform}>{children}</g>
|
|
285
|
-
</svg>
|
|
286
|
-
)
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
export default CanvasOverlay
|