@leafer-in/editor 1.0.0-rc.6 → 1.0.0-rc.7
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/dist/editor.esm.js +1122 -362
- package/dist/editor.esm.min.js +1 -1
- package/dist/editor.js +1134 -363
- package/dist/editor.min.js +1 -1
- package/package.json +4 -6
- package/src/Editor.ts +224 -150
- package/src/config.ts +29 -0
- package/src/decorator/data.ts +13 -0
- package/src/display/EditBox.ts +279 -0
- package/src/display/EditPoint.ts +9 -0
- package/src/display/EditSelect.ts +234 -0
- package/src/display/SelectArea.ts +30 -0
- package/src/display/Stroker.ts +89 -0
- package/src/editor/cursor.ts +58 -0
- package/src/editor/simulate.ts +14 -0
- package/src/editor/target.ts +38 -0
- package/src/event/EditorEvent.ts +23 -0
- package/src/event/EditorMoveEvent.ts +17 -0
- package/src/event/EditorRotateEvent.ts +4 -10
- package/src/event/EditorScaleEvent.ts +27 -0
- package/src/event/EditorSkewEvent.ts +18 -0
- package/src/helper/EditDataHelper.ts +149 -0
- package/src/helper/EditSelectHelper.ts +33 -0
- package/src/helper/EditorHelper.ts +95 -0
- package/src/index.ts +26 -3
- package/src/tool/EditTool.ts +70 -0
- package/src/tool/{LineTool.ts → LineEditTool.ts} +15 -24
- package/src/tool/index.ts +21 -0
- package/types/index.d.ts +193 -43
- package/src/cursor.ts +0 -57
- package/src/event/EditorResizeEvent.ts +0 -34
- package/src/resize.ts +0 -87
- package/src/tool/RectTool.ts +0 -141
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IGroup, ILeaf } from '@leafer-ui/interface'
|
|
2
|
+
import { Bounds } from '@leafer-ui/core'
|
|
3
|
+
|
|
4
|
+
import { IEditor } from '@leafer-in/interface'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export function simulate(editor: IEditor) {
|
|
8
|
+
const { simulateTarget, leafList: targetList } = editor
|
|
9
|
+
const { x, y, width, height } = new Bounds().setListWithFn(targetList.list, (leaf: ILeaf) => leaf.worldBoxBounds)
|
|
10
|
+
|
|
11
|
+
const parent = simulateTarget.parent = targetList.list[0].leafer.zoomLayer as IGroup
|
|
12
|
+
const { scaleX, scaleY, e: worldX, f: worldY } = parent.__world
|
|
13
|
+
simulateTarget.reset({ x: (x - worldX) / scaleX, y: (y - worldY) / scaleY, width: width / scaleX, height: height / scaleY })
|
|
14
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LeafList } from '@leafer-ui/core'
|
|
2
|
+
|
|
3
|
+
import { IEditor, IUI } from '@leafer-in/interface'
|
|
4
|
+
|
|
5
|
+
import { simulate } from './simulate'
|
|
6
|
+
import { updateMoveCursor } from './cursor'
|
|
7
|
+
import { EditorEvent } from '../event/EditorEvent'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export function onTarget(editor: IEditor): void {
|
|
11
|
+
const { target } = editor
|
|
12
|
+
if (target) {
|
|
13
|
+
editor.leafList = target instanceof LeafList ? target : new LeafList(target instanceof Array ? target : target as IUI)
|
|
14
|
+
} else {
|
|
15
|
+
editor.leafList.reset()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
editor.emitEvent(new EditorEvent(EditorEvent.SELECT, { editor }))
|
|
19
|
+
|
|
20
|
+
if (editor.hasTarget) {
|
|
21
|
+
editor.waitLeafer(() => {
|
|
22
|
+
if (editor.multiple) simulate(editor)
|
|
23
|
+
updateMoveCursor(editor)
|
|
24
|
+
editor.updateEditTool()
|
|
25
|
+
editor.update()
|
|
26
|
+
editor.listenTargetEvents()
|
|
27
|
+
})
|
|
28
|
+
} else {
|
|
29
|
+
editor.removeTargetEvents()
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
export function onHover(editor: IEditor): void {
|
|
36
|
+
editor.emitEvent(new EditorEvent(EditorEvent.HOVER, { editor }))
|
|
37
|
+
|
|
38
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { IUI, IPointData } from '@leafer-ui/interface'
|
|
2
|
+
import { Event } from '@leafer-ui/core'
|
|
3
|
+
|
|
4
|
+
import { IEditor, IEditorEvent } from '@leafer-in/interface'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export class EditorEvent extends Event implements IEditorEvent {
|
|
8
|
+
|
|
9
|
+
static SELECT = 'editor.select'
|
|
10
|
+
static HOVER = 'editor.hover'
|
|
11
|
+
|
|
12
|
+
declare readonly target: IUI
|
|
13
|
+
readonly editor: IEditor
|
|
14
|
+
|
|
15
|
+
readonly worldOrigin: IPointData
|
|
16
|
+
declare readonly origin: IPointData
|
|
17
|
+
|
|
18
|
+
constructor(type: string, data?: IEditorEvent) {
|
|
19
|
+
super(type)
|
|
20
|
+
if (data) Object.assign(this, data)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IEditorMoveEvent } from '@leafer-in/interface'
|
|
2
|
+
|
|
3
|
+
import { EditorEvent } from './EditorEvent'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export class EditorMoveEvent extends EditorEvent implements IEditorMoveEvent {
|
|
7
|
+
|
|
8
|
+
static MOVE = 'editor.move'
|
|
9
|
+
|
|
10
|
+
readonly moveX: number
|
|
11
|
+
readonly moveY: number
|
|
12
|
+
|
|
13
|
+
constructor(type: string, data?: IEditorMoveEvent) {
|
|
14
|
+
super(type, data)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
}
|
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { IEditor, IEditorRotateEvent } from '@leafer-in/interface'
|
|
1
|
+
import { IEditorRotateEvent } from '@leafer-in/interface'
|
|
3
2
|
|
|
4
|
-
import {
|
|
3
|
+
import { EditorEvent } from './EditorEvent'
|
|
5
4
|
|
|
6
5
|
|
|
7
|
-
export class EditorRotateEvent extends
|
|
6
|
+
export class EditorRotateEvent extends EditorEvent implements IEditorRotateEvent {
|
|
8
7
|
|
|
9
8
|
static ROTATE = 'editor.rotate'
|
|
10
9
|
|
|
11
|
-
declare readonly target: IUI
|
|
12
|
-
readonly editor: IEditor
|
|
13
|
-
|
|
14
10
|
// rotateOf(origin, rotation)
|
|
15
|
-
declare readonly origin: IPointData
|
|
16
11
|
readonly rotation: number
|
|
17
12
|
|
|
18
13
|
constructor(type: string, data?: IEditorRotateEvent) {
|
|
19
|
-
super(type)
|
|
20
|
-
if (data) Object.assign(this, data)
|
|
14
|
+
super(type, data)
|
|
21
15
|
}
|
|
22
16
|
|
|
23
17
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { IAround, IDragEvent, IMatrixData } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
import { IDirection8, IEditorScaleEvent } from '@leafer-in/interface'
|
|
4
|
+
|
|
5
|
+
import { EditorEvent } from './EditorEvent'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export class EditorScaleEvent extends EditorEvent implements IEditorScaleEvent {
|
|
9
|
+
|
|
10
|
+
static SCALE = 'editor.scale'
|
|
11
|
+
|
|
12
|
+
// scaleOf(origin, scaleX, scaleY, resize)
|
|
13
|
+
readonly scaleX: number
|
|
14
|
+
readonly scaleY: number
|
|
15
|
+
readonly transform?: IMatrixData
|
|
16
|
+
|
|
17
|
+
readonly drag: IDragEvent
|
|
18
|
+
|
|
19
|
+
readonly direction: IDirection8
|
|
20
|
+
readonly lockRatio: boolean
|
|
21
|
+
readonly around: IAround
|
|
22
|
+
|
|
23
|
+
constructor(type: string, data?: IEditorScaleEvent) {
|
|
24
|
+
super(type, data)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IEditorSkewEvent } from '@leafer-in/interface'
|
|
2
|
+
|
|
3
|
+
import { EditorEvent } from './EditorEvent'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export class EditorSkewEvent extends EditorEvent implements IEditorSkewEvent {
|
|
7
|
+
|
|
8
|
+
static SKEW = 'editor.skew'
|
|
9
|
+
|
|
10
|
+
// skewOf(origin, skewX, skewY)
|
|
11
|
+
readonly skewX: number
|
|
12
|
+
readonly skewY: number
|
|
13
|
+
|
|
14
|
+
constructor(type: string, data?: IEditorSkewEvent) {
|
|
15
|
+
super(type, data)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { IBoundsData, IPointData, IAround } from '@leafer-ui/interface'
|
|
2
|
+
import { AroundHelper, PointHelper } from '@leafer-ui/core'
|
|
3
|
+
|
|
4
|
+
import { IEditorScaleEvent, IDirection8, IEditorSkewEvent, IEditorRotateEvent } from '@leafer-in/interface'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const { topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left } = IDirection8
|
|
8
|
+
const { toPoint } = AroundHelper
|
|
9
|
+
|
|
10
|
+
export const EditDataHelper = {
|
|
11
|
+
|
|
12
|
+
getScaleData(bounds: IBoundsData, direction: IDirection8, pointMove: IPointData, lockRatio: boolean, around: IAround): IEditorScaleEvent {
|
|
13
|
+
let origin: IPointData, scaleX: number = 1, scaleY: number = 1
|
|
14
|
+
const { width, height } = bounds
|
|
15
|
+
|
|
16
|
+
if (around) {
|
|
17
|
+
pointMove.x *= 2
|
|
18
|
+
pointMove.y *= 2
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const topScale = (-pointMove.y + height) / height
|
|
22
|
+
const rightScale = (pointMove.x + width) / width
|
|
23
|
+
const bottomScale = (pointMove.y + height) / height
|
|
24
|
+
const leftScale = (-pointMove.x + width) / width
|
|
25
|
+
|
|
26
|
+
switch (direction) {
|
|
27
|
+
case top:
|
|
28
|
+
scaleY = topScale
|
|
29
|
+
origin = { x: 0.5, y: 1 }
|
|
30
|
+
break
|
|
31
|
+
case right:
|
|
32
|
+
scaleX = rightScale
|
|
33
|
+
origin = { x: 0, y: 0.5 }
|
|
34
|
+
break
|
|
35
|
+
case bottom:
|
|
36
|
+
scaleY = bottomScale
|
|
37
|
+
origin = { x: 0.5, y: 0 }
|
|
38
|
+
break
|
|
39
|
+
case left:
|
|
40
|
+
scaleX = leftScale
|
|
41
|
+
origin = { x: 1, y: 0.5 }
|
|
42
|
+
break
|
|
43
|
+
case topLeft:
|
|
44
|
+
scaleY = topScale
|
|
45
|
+
scaleX = leftScale
|
|
46
|
+
origin = { x: 1, y: 1 }
|
|
47
|
+
break
|
|
48
|
+
case topRight:
|
|
49
|
+
scaleY = topScale
|
|
50
|
+
scaleX = rightScale
|
|
51
|
+
origin = { x: 0, y: 1 }
|
|
52
|
+
break
|
|
53
|
+
case bottomRight:
|
|
54
|
+
scaleY = bottomScale
|
|
55
|
+
scaleX = rightScale
|
|
56
|
+
origin = { x: 0, y: 0 }
|
|
57
|
+
break
|
|
58
|
+
case bottomLeft:
|
|
59
|
+
scaleY = bottomScale
|
|
60
|
+
scaleX = leftScale
|
|
61
|
+
origin = { x: 1, y: 0 }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (lockRatio) {
|
|
65
|
+
if (scaleX !== 1) scaleY = scaleX
|
|
66
|
+
else scaleX = scaleY
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
toPoint(around || origin, bounds, origin)
|
|
70
|
+
|
|
71
|
+
return { origin, scaleX, scaleY, direction, lockRatio, around }
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
getRotateData(bounds: IBoundsData, direction: IDirection8, current: IPointData, last: IPointData, around: IAround): IEditorRotateEvent {
|
|
75
|
+
let origin: IPointData
|
|
76
|
+
|
|
77
|
+
switch (direction) {
|
|
78
|
+
case topLeft:
|
|
79
|
+
origin = { x: 1, y: 1 }
|
|
80
|
+
break
|
|
81
|
+
case topRight:
|
|
82
|
+
origin = { x: 0, y: 1 }
|
|
83
|
+
break
|
|
84
|
+
case bottomRight:
|
|
85
|
+
origin = { x: 0, y: 0 }
|
|
86
|
+
break
|
|
87
|
+
case bottomLeft:
|
|
88
|
+
origin = { x: 1, y: 0 }
|
|
89
|
+
break
|
|
90
|
+
default:
|
|
91
|
+
origin = { x: 0.5, y: 0.5 }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
toPoint(around || origin, bounds, origin)
|
|
95
|
+
|
|
96
|
+
return { origin, rotation: PointHelper.getRotation(last, origin, current) }
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
getSkewData(bounds: IBoundsData, direction: IDirection8, move: IPointData, around: IAround): IEditorSkewEvent {
|
|
100
|
+
let origin: IPointData, skewX = 0, skewY = 0
|
|
101
|
+
let last: IPointData
|
|
102
|
+
|
|
103
|
+
switch (direction) {
|
|
104
|
+
case top:
|
|
105
|
+
last = { x: 0.5, y: 0 }
|
|
106
|
+
origin = { x: 0.5, y: 1 }
|
|
107
|
+
skewX = 1
|
|
108
|
+
break
|
|
109
|
+
case bottom:
|
|
110
|
+
last = { x: 0.5, y: 1 }
|
|
111
|
+
origin = { x: 0.5, y: 0 }
|
|
112
|
+
skewX = 1
|
|
113
|
+
break
|
|
114
|
+
case left:
|
|
115
|
+
last = { x: 0, y: 0.5 }
|
|
116
|
+
origin = { x: 1, y: 0.5 }
|
|
117
|
+
skewY = 1
|
|
118
|
+
break
|
|
119
|
+
case right:
|
|
120
|
+
last = { x: 1, y: 0.5 }
|
|
121
|
+
origin = { x: 0, y: 0.5 }
|
|
122
|
+
skewY = 1
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const { x, y, width, height } = bounds
|
|
126
|
+
|
|
127
|
+
last.x = x + last.x * width
|
|
128
|
+
last.y = y + last.y * height
|
|
129
|
+
|
|
130
|
+
toPoint(around || origin, bounds, origin)
|
|
131
|
+
|
|
132
|
+
const rotation = PointHelper.getRotation(last, origin, { x: last.x + (skewX ? move.x : 0), y: last.y + (skewY ? move.y : 0) })
|
|
133
|
+
skewX ? skewX = -rotation : skewY = rotation
|
|
134
|
+
|
|
135
|
+
return { origin, skewX, skewY }
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
getAround(around: IAround, altKey: boolean): IAround {
|
|
140
|
+
return (altKey && !around) ? AroundHelper.center : around
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
getRotateDirection(direction: number, rotation: number, totalDirection = 8): number {
|
|
144
|
+
direction = (direction + Math.round(rotation / (360 / totalDirection))) % totalDirection
|
|
145
|
+
if (direction < 0) direction += totalDirection
|
|
146
|
+
return direction
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AnswerType, IBounds, ILeafList, IUI } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
const { No, Yes, NoAndSkip, YesAndSkip } = AnswerType
|
|
4
|
+
|
|
5
|
+
export const EditSelectHelper = {
|
|
6
|
+
|
|
7
|
+
findOne(path: ILeafList): IUI {
|
|
8
|
+
return path.list.find((leaf) => leaf.editable) as IUI
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
findBounds(leaf: IUI, bounds: IBounds): AnswerType {
|
|
12
|
+
if (leaf.__.hittable && !leaf.__.locked && bounds.hit(leaf.__world)) {
|
|
13
|
+
|
|
14
|
+
if (leaf.__.editable) {
|
|
15
|
+
if (leaf.isBranch && !leaf.__.hitChildren) {
|
|
16
|
+
return leaf.__.hitSelf ? YesAndSkip : NoAndSkip
|
|
17
|
+
} else if (leaf.isFrame) {
|
|
18
|
+
return bounds.includes(leaf.__layout.boxBounds, leaf.__world) ? YesAndSkip : No
|
|
19
|
+
} else {
|
|
20
|
+
if (bounds.hit(leaf.__layout.boxBounds, leaf.__world) && leaf.__.hitSelf) return Yes
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return No
|
|
25
|
+
|
|
26
|
+
} else {
|
|
27
|
+
|
|
28
|
+
return leaf.isBranch ? NoAndSkip : No
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { IGroup, ILeaf, IUI } from '@leafer-ui/interface'
|
|
2
|
+
import { Group, Matrix } from '@leafer-ui/core'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const order = (a: ILeaf, b: ILeaf) => a.parent.children.indexOf(a) - b.parent.children.indexOf(b)
|
|
6
|
+
const reverseOrder = (a: ILeaf, b: ILeaf) => b.parent.children.indexOf(b) - a.parent.children.indexOf(a)
|
|
7
|
+
|
|
8
|
+
export const EditorHelper = {
|
|
9
|
+
|
|
10
|
+
group(list: IUI[], element?: IUI, group?: IGroup): IGroup {
|
|
11
|
+
list.sort(reverseOrder)
|
|
12
|
+
const { app, parent } = list[0]
|
|
13
|
+
if (!group) group = new Group()
|
|
14
|
+
parent.addAt(group, parent.children.indexOf(list[0]))
|
|
15
|
+
list.sort(order)
|
|
16
|
+
|
|
17
|
+
const matrx = new Matrix(element.worldTransform)
|
|
18
|
+
matrx.divideParent(parent.worldTransform)
|
|
19
|
+
group.setTransform(matrx)
|
|
20
|
+
group.editable = true
|
|
21
|
+
group.hitChildren = false
|
|
22
|
+
|
|
23
|
+
app.lockLayout()
|
|
24
|
+
list.forEach(child => child.dropTo(group))
|
|
25
|
+
app.unlockLayout()
|
|
26
|
+
|
|
27
|
+
return group
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
ungroup(list: IUI[]): IUI[] {
|
|
31
|
+
const { app } = list[0]
|
|
32
|
+
const ungroupList: IUI[] = []
|
|
33
|
+
|
|
34
|
+
app.lockLayout()
|
|
35
|
+
list.forEach(leaf => {
|
|
36
|
+
if (leaf.isBranch) {
|
|
37
|
+
const { parent, children } = leaf
|
|
38
|
+
while (children.length) {
|
|
39
|
+
ungroupList.push(children[0])
|
|
40
|
+
children[0].dropTo(parent, parent.children.indexOf(leaf))
|
|
41
|
+
}
|
|
42
|
+
leaf.remove()
|
|
43
|
+
} else {
|
|
44
|
+
ungroupList.push(leaf)
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
app.unlockLayout()
|
|
48
|
+
|
|
49
|
+
return ungroupList
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
toTop(list: IUI[]): void {
|
|
53
|
+
list.sort(order)
|
|
54
|
+
list.forEach(leaf => {
|
|
55
|
+
let zIndex
|
|
56
|
+
const { parent } = leaf
|
|
57
|
+
if (parent) {
|
|
58
|
+
const { children } = parent
|
|
59
|
+
const top = children.length - 1
|
|
60
|
+
const zIndexOfTop = children[top].__.zIndex
|
|
61
|
+
const current = children.indexOf(leaf)
|
|
62
|
+
if (current !== top) {
|
|
63
|
+
children.splice(current, 1)
|
|
64
|
+
children.push(leaf)
|
|
65
|
+
zIndex = zIndexOfTop + 1
|
|
66
|
+
} else {
|
|
67
|
+
zIndex = zIndexOfTop
|
|
68
|
+
}
|
|
69
|
+
leaf.zIndex = zIndex
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
toBottom(list: IUI[]): void {
|
|
75
|
+
list.sort(reverseOrder)
|
|
76
|
+
list.forEach(leaf => {
|
|
77
|
+
let zIndex
|
|
78
|
+
const { parent } = leaf
|
|
79
|
+
if (parent) {
|
|
80
|
+
const { children } = parent
|
|
81
|
+
const zIndexOfBottom = children[0].__.zIndex
|
|
82
|
+
const current = children.indexOf(leaf)
|
|
83
|
+
if (current !== 0) {
|
|
84
|
+
children.splice(current, 1)
|
|
85
|
+
children.unshift(leaf)
|
|
86
|
+
zIndex = zIndexOfBottom - 1
|
|
87
|
+
} else {
|
|
88
|
+
zIndex = zIndexOfBottom
|
|
89
|
+
}
|
|
90
|
+
leaf.zIndex = zIndex
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
export { Editor } from './Editor'
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
export { EditBox } from './display/EditBox'
|
|
4
|
+
export { EditPoint } from './display/EditPoint'
|
|
5
|
+
export { EditSelect } from './display/EditSelect'
|
|
6
|
+
export { SelectArea } from './display/SelectArea'
|
|
7
|
+
export { Stroker } from './display/Stroker'
|
|
8
|
+
|
|
9
|
+
export { EditorEvent } from './event/EditorEvent'
|
|
10
|
+
export { EditorMoveEvent } from './event/EditorMoveEvent'
|
|
11
|
+
export { EditorScaleEvent } from './event/EditorScaleEvent'
|
|
3
12
|
export { EditorRotateEvent } from './event/EditorRotateEvent'
|
|
4
|
-
export {
|
|
5
|
-
|
|
13
|
+
export { EditorSkewEvent } from './event/EditorSkewEvent'
|
|
14
|
+
|
|
15
|
+
export { LineEditTool } from './tool/LineEditTool'
|
|
16
|
+
export { EditTool } from './tool/EditTool'
|
|
17
|
+
|
|
18
|
+
export { EditorHelper } from './helper/EditorHelper'
|
|
19
|
+
export { EditDataHelper } from './helper/EditDataHelper'
|
|
20
|
+
export { EditSelectHelper } from './helper/EditSelectHelper'
|
|
21
|
+
|
|
22
|
+
import { IEditor, IEditorConfig } from '@leafer-in/interface'
|
|
23
|
+
import { Creator } from '@leafer-ui/core'
|
|
24
|
+
import { Editor } from './Editor'
|
|
25
|
+
|
|
26
|
+
Creator.editor = function (options?: IEditorConfig): IEditor {
|
|
27
|
+
return new Editor(options)
|
|
28
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { IEditor, IEditorScaleEvent, IEditorRotateEvent, IEditTool, IEditorSkewEvent, IEditorMoveEvent } from '@leafer-in/interface'
|
|
2
|
+
|
|
3
|
+
export class EditTool implements IEditTool {
|
|
4
|
+
|
|
5
|
+
static list: IEditTool[] = []
|
|
6
|
+
|
|
7
|
+
public tag = 'EditTool'
|
|
8
|
+
|
|
9
|
+
onMove(e: IEditorMoveEvent): void {
|
|
10
|
+
const { moveX, moveY, editor } = e
|
|
11
|
+
const { app, list } = editor
|
|
12
|
+
app.lockLayout()
|
|
13
|
+
list.forEach(target => {
|
|
14
|
+
const move = target.getLocalPoint({ x: moveX, y: moveY }, null, true)
|
|
15
|
+
target.move(move.x, move.y)
|
|
16
|
+
})
|
|
17
|
+
app.unlockLayout()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
onScale(e: IEditorScaleEvent): void {
|
|
21
|
+
const { scaleX, scaleY, transform, worldOrigin, editor } = e
|
|
22
|
+
const { app, list } = editor
|
|
23
|
+
app.lockLayout()
|
|
24
|
+
list.forEach(target => {
|
|
25
|
+
const resize = editor.getEditSize(target) === 'size'
|
|
26
|
+
if (transform) {
|
|
27
|
+
target.transform(transform, resize)
|
|
28
|
+
} else {
|
|
29
|
+
target.scaleOf(target.getInnerPoint(worldOrigin), scaleX, scaleY, resize)
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
app.unlockLayout()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
onRotate(e: IEditorRotateEvent): void {
|
|
36
|
+
const { rotation, worldOrigin, editor } = e
|
|
37
|
+
const { app, list } = editor
|
|
38
|
+
app.lockLayout()
|
|
39
|
+
list.forEach(target => {
|
|
40
|
+
target.rotateOf(target.getInnerPoint(worldOrigin), rotation)
|
|
41
|
+
})
|
|
42
|
+
app.unlockLayout()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
onSkew(e: IEditorSkewEvent): void {
|
|
46
|
+
const { skewX, skewY, transform, worldOrigin, editor } = e
|
|
47
|
+
const { app, list } = editor
|
|
48
|
+
app.lockLayout()
|
|
49
|
+
list.forEach(target => {
|
|
50
|
+
const resize = editor.getEditSize(target) === 'size'
|
|
51
|
+
if (transform) {
|
|
52
|
+
target.transform(transform, resize)
|
|
53
|
+
} else {
|
|
54
|
+
target.skewOf(target.getInnerPoint(worldOrigin), skewX, skewY, resize)
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
app.unlockLayout()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
update(editor: IEditor) {
|
|
61
|
+
const { simulateTarget, element } = editor
|
|
62
|
+
|
|
63
|
+
if (editor.multiple) simulateTarget.parent.updateLayout()
|
|
64
|
+
|
|
65
|
+
const { x, y, scaleX, scaleY, rotation, skewX, skewY, width, height } = element.getLayoutBounds('box', editor, true)
|
|
66
|
+
editor.editBox.set({ x, y, scaleX, scaleY, rotation, skewX, skewY })
|
|
67
|
+
editor.editBox.update({ x: 0, y: 0, width, height })
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}
|
|
@@ -1,23 +1,18 @@
|
|
|
1
|
-
import { IDirection8, IEditor,
|
|
1
|
+
import { IDirection8, IEditor, IEditorScaleEvent, ILine, IEditorSkewEvent } from '@leafer-in/interface'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { EditTool } from './EditTool'
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
const { left, right } = IDirection8
|
|
7
7
|
|
|
8
|
-
export
|
|
8
|
+
export class LineEditTool extends EditTool {
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
public tag = 'LineEditTool'
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
return {
|
|
14
|
-
x: 0,
|
|
15
|
-
y: 0
|
|
16
|
-
}
|
|
17
|
-
},
|
|
12
|
+
public scaleOfEvent = true
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
const {
|
|
14
|
+
onScaleWithDrag(e: IEditorScaleEvent): void {
|
|
15
|
+
const { drag, direction, lockRatio, around } = e
|
|
21
16
|
const target = e.target as ILine
|
|
22
17
|
|
|
23
18
|
const fromPoint = { x: 0, y: 0 }
|
|
@@ -25,7 +20,7 @@ export const LineTool: IEditorTool = {
|
|
|
25
20
|
|
|
26
21
|
target.rotation = 0
|
|
27
22
|
|
|
28
|
-
let { x, y } =
|
|
23
|
+
let { x, y } = drag.getInnerMove(target)
|
|
29
24
|
|
|
30
25
|
if (lockRatio) {
|
|
31
26
|
if (Math.abs(x) > Math.abs(y)) {
|
|
@@ -65,24 +60,20 @@ export const LineTool: IEditorTool = {
|
|
|
65
60
|
target.getInnerPointByLocal(toPoint, null, null, true)
|
|
66
61
|
target.toPoint = toPoint
|
|
67
62
|
|
|
68
|
-
}
|
|
63
|
+
}
|
|
69
64
|
|
|
70
|
-
|
|
71
|
-
RectTool.rotate(e)
|
|
72
|
-
},
|
|
65
|
+
onSkew(_e: IEditorSkewEvent): void {
|
|
73
66
|
|
|
74
|
-
|
|
67
|
+
}
|
|
75
68
|
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
update(editor: IEditor) {
|
|
70
|
+
const { rotatePoints, resizeLines, resizePoints } = editor.editBox
|
|
71
|
+
super.update(editor)
|
|
78
72
|
|
|
79
73
|
for (let i = 0; i < 8; i++) {
|
|
80
74
|
if (i < 4) resizeLines[i].visible = false
|
|
81
|
-
resizePoints[i].visible = rotatePoints[i].visible = i === left || i === right
|
|
75
|
+
resizePoints[i].visible = rotatePoints[i].visible = (i === left || i === right)
|
|
82
76
|
}
|
|
83
|
-
|
|
84
|
-
circle.visible = false
|
|
85
|
-
|
|
86
77
|
}
|
|
87
78
|
|
|
88
79
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IUI } from '@leafer-ui/interface'
|
|
2
|
+
import { Line } from '@leafer-ui/core'
|
|
3
|
+
|
|
4
|
+
import { IEditTool } from '@leafer-in/interface'
|
|
5
|
+
|
|
6
|
+
import { EditTool } from './EditTool'
|
|
7
|
+
import { LineEditTool } from './LineEditTool'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export function getEditTool(list: IUI[]): IEditTool {
|
|
11
|
+
if (list.length === 1) {
|
|
12
|
+
const leaf = list[0]
|
|
13
|
+
if (leaf instanceof Line && !leaf.points) {
|
|
14
|
+
return new LineEditTool()
|
|
15
|
+
} else {
|
|
16
|
+
return new EditTool()
|
|
17
|
+
}
|
|
18
|
+
} else {
|
|
19
|
+
return new EditTool()
|
|
20
|
+
}
|
|
21
|
+
}
|