@leafer-in/editor 1.0.0-beta.18 → 1.0.0-rc.11
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 +1359 -387
- package/dist/editor.esm.min.js +1 -1
- package/dist/editor.js +1372 -390
- package/dist/editor.min.js +1 -1
- package/package.json +5 -6
- package/src/Editor.ts +234 -149
- package/src/config.ts +32 -0
- package/src/decorator/data.ts +16 -0
- package/src/display/EditBox.ts +273 -0
- package/src/display/EditPoint.ts +9 -0
- package/src/display/EditSelect.ts +236 -0
- package/src/display/SelectArea.ts +30 -0
- package/src/display/Stroker.ts +89 -0
- package/src/editor/cursor.ts +34 -0
- package/src/editor/simulate.ts +14 -0
- package/src/editor/target.ts +37 -0
- package/src/event/EditorEvent.ts +26 -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 +179 -0
- package/src/helper/EditSelectHelper.ts +34 -0
- package/src/helper/EditorHelper.ts +73 -0
- package/src/index.ts +28 -3
- package/src/svg.ts +54 -0
- package/src/tool/EditTool.ts +78 -0
- package/src/tool/{LineTool.ts → LineEditTool.ts} +19 -25
- package/src/tool/index.ts +21 -0
- package/types/index.d.ts +196 -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 -139
|
@@ -0,0 +1,37 @@
|
|
|
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, oldValue: IUI | IUI[]): 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, value: target, oldValue }))
|
|
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
|
+
export function onHover(editor: IEditor, oldValue: IUI): void {
|
|
35
|
+
editor.emitEvent(new EditorEvent(EditorEvent.HOVER, { editor, value: editor.hoverTarget, oldValue }))
|
|
36
|
+
|
|
37
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
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 value: IUI | IUI[]
|
|
16
|
+
readonly oldValue: IUI | IUI[]
|
|
17
|
+
|
|
18
|
+
readonly worldOrigin: IPointData
|
|
19
|
+
declare readonly origin: IPointData
|
|
20
|
+
|
|
21
|
+
constructor(type: string, data?: IEditorEvent) {
|
|
22
|
+
super(type)
|
|
23
|
+
if (data) Object.assign(this, data)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
}
|
|
@@ -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
|
-
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,179 @@
|
|
|
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
|
+
// 防止变为0
|
|
22
|
+
if (Math.abs(pointMove.x) === width) pointMove.x += 0.1
|
|
23
|
+
if (Math.abs(pointMove.y) === height) pointMove.y += 0.1
|
|
24
|
+
|
|
25
|
+
const topScale = (-pointMove.y + height) / height
|
|
26
|
+
const rightScale = (pointMove.x + width) / width
|
|
27
|
+
const bottomScale = (pointMove.y + height) / height
|
|
28
|
+
const leftScale = (-pointMove.x + width) / width
|
|
29
|
+
|
|
30
|
+
switch (direction) {
|
|
31
|
+
case top:
|
|
32
|
+
scaleY = topScale
|
|
33
|
+
origin = { x: 0.5, y: 1 }
|
|
34
|
+
break
|
|
35
|
+
case right:
|
|
36
|
+
scaleX = rightScale
|
|
37
|
+
origin = { x: 0, y: 0.5 }
|
|
38
|
+
break
|
|
39
|
+
case bottom:
|
|
40
|
+
scaleY = bottomScale
|
|
41
|
+
origin = { x: 0.5, y: 0 }
|
|
42
|
+
break
|
|
43
|
+
case left:
|
|
44
|
+
scaleX = leftScale
|
|
45
|
+
origin = { x: 1, y: 0.5 }
|
|
46
|
+
break
|
|
47
|
+
case topLeft:
|
|
48
|
+
scaleY = topScale
|
|
49
|
+
scaleX = leftScale
|
|
50
|
+
origin = { x: 1, y: 1 }
|
|
51
|
+
break
|
|
52
|
+
case topRight:
|
|
53
|
+
scaleY = topScale
|
|
54
|
+
scaleX = rightScale
|
|
55
|
+
origin = { x: 0, y: 1 }
|
|
56
|
+
break
|
|
57
|
+
case bottomRight:
|
|
58
|
+
scaleY = bottomScale
|
|
59
|
+
scaleX = rightScale
|
|
60
|
+
origin = { x: 0, y: 0 }
|
|
61
|
+
break
|
|
62
|
+
case bottomLeft:
|
|
63
|
+
scaleY = bottomScale
|
|
64
|
+
scaleX = leftScale
|
|
65
|
+
origin = { x: 1, y: 0 }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (lockRatio) {
|
|
69
|
+
if (scaleX !== 1) scaleY = scaleX
|
|
70
|
+
else scaleX = scaleY
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
toPoint(around || origin, bounds, origin)
|
|
74
|
+
|
|
75
|
+
return { origin, scaleX, scaleY, direction, lockRatio, around }
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
getRotateData(bounds: IBoundsData, direction: IDirection8, current: IPointData, last: IPointData, around: IAround): IEditorRotateEvent {
|
|
79
|
+
let origin: IPointData
|
|
80
|
+
|
|
81
|
+
switch (direction) {
|
|
82
|
+
case topLeft:
|
|
83
|
+
origin = { x: 1, y: 1 }
|
|
84
|
+
break
|
|
85
|
+
case topRight:
|
|
86
|
+
origin = { x: 0, y: 1 }
|
|
87
|
+
break
|
|
88
|
+
case bottomRight:
|
|
89
|
+
origin = { x: 0, y: 0 }
|
|
90
|
+
break
|
|
91
|
+
case bottomLeft:
|
|
92
|
+
origin = { x: 1, y: 0 }
|
|
93
|
+
break
|
|
94
|
+
default:
|
|
95
|
+
origin = { x: 0.5, y: 0.5 }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
toPoint(around || origin, bounds, origin)
|
|
99
|
+
|
|
100
|
+
return { origin, rotation: PointHelper.getRotation(last, origin, current) }
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
getSkewData(bounds: IBoundsData, direction: IDirection8, move: IPointData, around: IAround): IEditorSkewEvent {
|
|
104
|
+
let origin: IPointData, skewX = 0, skewY = 0
|
|
105
|
+
let last: IPointData
|
|
106
|
+
|
|
107
|
+
switch (direction) {
|
|
108
|
+
case top:
|
|
109
|
+
last = { x: 0.5, y: 0 }
|
|
110
|
+
origin = { x: 0.5, y: 1 }
|
|
111
|
+
skewX = 1
|
|
112
|
+
break
|
|
113
|
+
case bottom:
|
|
114
|
+
last = { x: 0.5, y: 1 }
|
|
115
|
+
origin = { x: 0.5, y: 0 }
|
|
116
|
+
skewX = 1
|
|
117
|
+
break
|
|
118
|
+
case left:
|
|
119
|
+
last = { x: 0, y: 0.5 }
|
|
120
|
+
origin = { x: 1, y: 0.5 }
|
|
121
|
+
skewY = 1
|
|
122
|
+
break
|
|
123
|
+
case right:
|
|
124
|
+
last = { x: 1, y: 0.5 }
|
|
125
|
+
origin = { x: 0, y: 0.5 }
|
|
126
|
+
skewY = 1
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const { x, y, width, height } = bounds
|
|
130
|
+
|
|
131
|
+
last.x = x + last.x * width
|
|
132
|
+
last.y = y + last.y * height
|
|
133
|
+
|
|
134
|
+
toPoint(around || origin, bounds, origin)
|
|
135
|
+
|
|
136
|
+
const rotation = PointHelper.getRotation(last, origin, { x: last.x + (skewX ? move.x : 0), y: last.y + (skewY ? move.y : 0) })
|
|
137
|
+
skewX ? skewX = -rotation : skewY = rotation
|
|
138
|
+
|
|
139
|
+
return { origin, skewX, skewY }
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
getAround(around: IAround, altKey: boolean): IAround {
|
|
144
|
+
return (altKey && !around) ? 'center' : around
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
getRotateDirection(direction: number, rotation: number, totalDirection = 8): number {
|
|
148
|
+
direction = (direction + Math.round(rotation / (360 / totalDirection))) % totalDirection
|
|
149
|
+
if (direction < 0) direction += totalDirection
|
|
150
|
+
return direction
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
getFlipDirection(direction: IDirection8, flipedX: boolean, flipedY: boolean): IDirection8 {
|
|
154
|
+
if (flipedX) {
|
|
155
|
+
switch (direction) {
|
|
156
|
+
case left: direction = right; break
|
|
157
|
+
case topLeft: direction = topRight; break
|
|
158
|
+
case bottomLeft: direction = bottomRight; break
|
|
159
|
+
case right: direction = left; break
|
|
160
|
+
case topRight: direction = topLeft; break
|
|
161
|
+
case bottomRight: direction = bottomLeft; break
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (flipedY) {
|
|
166
|
+
switch (direction) {
|
|
167
|
+
case top: direction = bottom; break
|
|
168
|
+
case topLeft: direction = bottomLeft; break
|
|
169
|
+
case topRight: direction = bottomRight; break
|
|
170
|
+
case bottom: direction = top; break
|
|
171
|
+
case bottomLeft: direction = topLeft; break
|
|
172
|
+
case bottomRight: direction = topRight; break
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return direction
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { IBounds, ILeafList, IUI } from '@leafer-ui/interface'
|
|
2
|
+
import { Answer } from '@leafer-ui/core'
|
|
3
|
+
|
|
4
|
+
const { No, Yes, NoAndSkip, YesAndSkip } = Answer
|
|
5
|
+
|
|
6
|
+
export const EditSelectHelper = {
|
|
7
|
+
|
|
8
|
+
findOne(path: ILeafList): IUI {
|
|
9
|
+
return path.list.find((leaf) => leaf.editable) as IUI
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
findBounds(leaf: IUI, bounds: IBounds): Answer {
|
|
13
|
+
if (leaf.__.hittable && leaf.__.visible && !leaf.__.locked && bounds.hit(leaf.__world)) {
|
|
14
|
+
|
|
15
|
+
if (leaf.__.editable) {
|
|
16
|
+
if (leaf.isBranch && !leaf.__.hitChildren) {
|
|
17
|
+
return leaf.__.hitSelf ? YesAndSkip : NoAndSkip
|
|
18
|
+
} else if (leaf.isFrame) {
|
|
19
|
+
return bounds.includes(leaf.__layout.boxBounds, leaf.__world) ? YesAndSkip : No
|
|
20
|
+
} else {
|
|
21
|
+
if (bounds.hit(leaf.__layout.boxBounds, leaf.__world) && leaf.__.hitSelf) return Yes
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return No
|
|
26
|
+
|
|
27
|
+
} else {
|
|
28
|
+
|
|
29
|
+
return leaf.isBranch ? NoAndSkip : No
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { IGroup, IGroupInputData, 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, userGroup?: IGroup | IGroupInputData): IGroup {
|
|
11
|
+
list.sort(reverseOrder)
|
|
12
|
+
const { app, parent } = list[0]
|
|
13
|
+
|
|
14
|
+
let group: IGroup
|
|
15
|
+
if (userGroup && (userGroup as IGroup).add) {
|
|
16
|
+
group = userGroup as IGroup
|
|
17
|
+
} else {
|
|
18
|
+
group = new Group(userGroup)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
parent.addAt(group, parent.children.indexOf(list[0]))
|
|
22
|
+
list.sort(order)
|
|
23
|
+
|
|
24
|
+
const matrx = new Matrix(element.worldTransform)
|
|
25
|
+
matrx.divideParent(parent.worldTransform)
|
|
26
|
+
group.setTransform(matrx)
|
|
27
|
+
group.editable = true
|
|
28
|
+
group.hitChildren = false
|
|
29
|
+
|
|
30
|
+
app.lockLayout()
|
|
31
|
+
list.forEach(child => child.dropTo(group))
|
|
32
|
+
app.unlockLayout()
|
|
33
|
+
|
|
34
|
+
return group
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
ungroup(list: IUI[]): IUI[] {
|
|
38
|
+
const { app } = list[0]
|
|
39
|
+
const ungroupList: IUI[] = []
|
|
40
|
+
|
|
41
|
+
app.lockLayout()
|
|
42
|
+
list.forEach(leaf => {
|
|
43
|
+
if (leaf.isBranch) {
|
|
44
|
+
const { parent, children } = leaf
|
|
45
|
+
while (children.length) {
|
|
46
|
+
ungroupList.push(children[0])
|
|
47
|
+
children[0].dropTo(parent, parent.children.indexOf(leaf))
|
|
48
|
+
}
|
|
49
|
+
leaf.remove()
|
|
50
|
+
} else {
|
|
51
|
+
ungroupList.push(leaf)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
app.unlockLayout()
|
|
55
|
+
|
|
56
|
+
return ungroupList
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
toTop(list: IUI[]): void {
|
|
60
|
+
list.sort(order)
|
|
61
|
+
list.forEach(leaf => {
|
|
62
|
+
if (leaf.parent) leaf.parent.add(leaf)
|
|
63
|
+
})
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
toBottom(list: IUI[]): void {
|
|
67
|
+
list.sort(reverseOrder)
|
|
68
|
+
list.forEach(leaf => {
|
|
69
|
+
if (leaf.parent) leaf.parent.addAt(leaf, 0)
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
|
+
export * from '@leafer-ui/scale'
|
|
2
|
+
|
|
1
3
|
export { Editor } from './Editor'
|
|
2
|
-
|
|
4
|
+
|
|
5
|
+
export { EditBox } from './display/EditBox'
|
|
6
|
+
export { EditPoint } from './display/EditPoint'
|
|
7
|
+
export { EditSelect } from './display/EditSelect'
|
|
8
|
+
export { SelectArea } from './display/SelectArea'
|
|
9
|
+
export { Stroker } from './display/Stroker'
|
|
10
|
+
|
|
11
|
+
export { EditorEvent } from './event/EditorEvent'
|
|
12
|
+
export { EditorMoveEvent } from './event/EditorMoveEvent'
|
|
13
|
+
export { EditorScaleEvent } from './event/EditorScaleEvent'
|
|
3
14
|
export { EditorRotateEvent } from './event/EditorRotateEvent'
|
|
4
|
-
export {
|
|
5
|
-
|
|
15
|
+
export { EditorSkewEvent } from './event/EditorSkewEvent'
|
|
16
|
+
|
|
17
|
+
export { LineEditTool } from './tool/LineEditTool'
|
|
18
|
+
export { EditTool } from './tool/EditTool'
|
|
19
|
+
|
|
20
|
+
export { EditorHelper } from './helper/EditorHelper'
|
|
21
|
+
export { EditDataHelper } from './helper/EditDataHelper'
|
|
22
|
+
export { EditSelectHelper } from './helper/EditSelectHelper'
|
|
23
|
+
|
|
24
|
+
import { IEditor, IEditorConfig } from '@leafer-in/interface'
|
|
25
|
+
import { Creator } from '@leafer-ui/core'
|
|
26
|
+
import { Editor } from './Editor'
|
|
27
|
+
|
|
28
|
+
Creator.editor = function (options?: IEditorConfig): IEditor {
|
|
29
|
+
return new Editor(options)
|
|
30
|
+
}
|
package/src/svg.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const filterStyle = `
|
|
2
|
+
<feOffset dy="1"/>
|
|
3
|
+
<feGaussianBlur stdDeviation="1.5"/>
|
|
4
|
+
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
|
|
5
|
+
<feBlend mode="normal" in="SourceGraphic" result="shape"/>`
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export const resizeSVG = `
|
|
9
|
+
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
|
10
|
+
<g filter="url(#f)">
|
|
11
|
+
<g transform="rotate({{rotation}},12,12)">
|
|
12
|
+
<path d="M7.5 8.0H8.5V5.9L6.8 7.2L7.5 8.0ZM3 11.4L2.3 10.6L1.3 11.4L2.3 12.2L3 11.4ZM7.5 10.4H6.5V11.4H7.5V10.4ZM16.5 10.4V11.4H17.5V10.4H16.5ZM16.5 8.0L17.1 7.2L15.5 5.9V8.0H16.5ZM21 11.4L21.6 12.2L22.6 11.4L21.6 10.6L21 11.4ZM16.5 14.9H15.5V16.9L17.1 15.7L16.5 14.9ZM16.5 12.4H17.5V11.4H16.5V12.4ZM7.5 12.4V11.4H6.5V12.4H7.5ZM7.5 14.9L6.8 15.7L8.5 16.9V14.9H7.5ZM6.8 7.2L2.3 10.6L3.6 12.2L8.1 8.7L6.8 7.2ZM8.5 10.4V8.0H6.5V10.4H8.5ZM16.5 9.4H7.5V11.4H16.5V9.4ZM17.5 10.4V8.0H15.5V10.4H17.5ZM15.8 8.7L20.3 12.2L21.6 10.6L17.1 7.2L15.8 8.7ZM20.3 10.6L15.8 14.1L17.1 15.7L21.6 12.2L20.3 10.6ZM17.5 14.9V12.4H15.5V14.9H17.5ZM7.5 13.4H16.5V11.4H7.5V13.4ZM8.5 14.9V12.4H6.5V14.9H8.5ZM2.3 12.2L6.8 15.7L8.1 14.1L3.6 10.6L2.3 12.2Z" fill="white"/>
|
|
13
|
+
<path fill-rule="evenodd" d="M3 11.4L7.5 8.0V10.4H16.5V8.0L21 11.4L16.5 14.9V12.4H7.5V14.9L3 11.4Z" fill="black"/>
|
|
14
|
+
</g>
|
|
15
|
+
</g>
|
|
16
|
+
<defs>
|
|
17
|
+
<filter id="f" x="-1.6" y="3.9" width="27.2" height="16.9" filterUnits="userSpaceOnUse">
|
|
18
|
+
${filterStyle}
|
|
19
|
+
</filter>
|
|
20
|
+
</defs>
|
|
21
|
+
</svg>
|
|
22
|
+
`
|
|
23
|
+
|
|
24
|
+
export const rotateSVG = `
|
|
25
|
+
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
|
26
|
+
<g filter="url(#f)">
|
|
27
|
+
<g transform="rotate(135,12,12),rotate({{rotation}},12,12)">
|
|
28
|
+
<path d="M20.4 8H21.4L20.8 7.1L17.3 2.6L17 2.1L16.6 2.6L13.1 7.1L12.5 8H13.5H15.4C14.9 11.8 11.8 14.9 8 15.4V13.5V12.5L7.1 13.1L2.6 16.6L2.1 17L2.6 17.3L7.1 20.8L8 21.4V20.4V18.4C13.5 17.9 17.9 13.5 18.4 8H20.4Z" stroke="white"/>
|
|
29
|
+
<path fill-rule="evenodd" d="M17 3L20.4 7.5H17.9C17.7 13.1 13.1 17.7 7.5 17.9V20.4L3 17L7.5 13.5V15.9C12.0 15.7 15.7 12.0 15.9 7.5H13.5L17 3Z" fill="black"/>
|
|
30
|
+
</g>
|
|
31
|
+
</g>
|
|
32
|
+
<defs>
|
|
33
|
+
<filter id="f" x="-1.6" y="-0.6" width="27.1" height="27.1" filterUnits="userSpaceOnUse">
|
|
34
|
+
${filterStyle}
|
|
35
|
+
</filter>
|
|
36
|
+
</defs>
|
|
37
|
+
</svg>
|
|
38
|
+
`
|
|
39
|
+
|
|
40
|
+
export const skewSVG = `
|
|
41
|
+
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
|
42
|
+
<g filter="url(#f)">
|
|
43
|
+
<g transform="rotate(90,12,12),rotate({{rotation}},12,12)">
|
|
44
|
+
<path d="M21 10.4L21 11.4L23.8 11.4L21.6 9.6L21 10.4ZM17 10.4V11.4L17 11.4L17 10.4ZM15.5 6L16.1 5.2L14.5 3.9V6H15.5ZM15.5 8.4V9.4H16.5V8.4H15.5ZM6 8.4V7.4H5V8.4H6ZM6 10.4H5V11.4H6V10.4ZM7 14.4V13.4L7 13.4L7 14.4ZM3 14.4L3 13.4L0.1 13.4L2.3 15.2L3 14.4ZM8.5 18.9L7.8 19.7L9.5 21.0V18.9H8.5ZM8.5 16.4V15.4H7.5V16.4H8.5ZM19 16.4V17.4H20V16.4H19ZM19 14.4H20V13.4H19V14.4ZM21 9.4L17 9.4L17 11.4L21 11.4L21 9.4ZM14.8 6.7L20.3 11.2L21.6 9.6L16.1 5.2L14.8 6.7ZM16.5 8.4V6H14.5V8.4H16.5ZM6 9.4H15.5V7.4H6V9.4ZM7 10.4V8.4H5V10.4H7ZM15.5 9.4H6V11.4H15.5V9.4ZM17 9.4H15.5V11.4H17V9.4ZM7 15.4H8.5V13.4H7V15.4ZM3 15.4L7 15.4L7 13.4L3 13.4L3 15.4ZM9.1 18.1L3.6 13.6L2.3 15.2L7.8 19.7L9.1 18.1ZM7.5 16.4V18.9H9.5V16.4H7.5ZM19 15.4H8.5V17.4H19V15.4ZM18 14.4V16.4H20V14.4H18ZM8.5 15.4H19V13.4H8.5V15.4Z" fill="white"/>
|
|
45
|
+
<path fill-rule="evenodd" d="M17 10.4L21 10.4L15.5 6V8.4H6V10.4H15.5H17ZM8.5 14.4H7L3 14.4L8.5 18.9V16.4H19V14.4H8.5Z" fill="black"/>
|
|
46
|
+
</g>
|
|
47
|
+
</g>
|
|
48
|
+
<defs>
|
|
49
|
+
<filter x="-2.8" y="1.9" width="29.6" height="23.1" filterUnits="userSpaceOnUse" >
|
|
50
|
+
${filterStyle}
|
|
51
|
+
</filter>
|
|
52
|
+
</defs>
|
|
53
|
+
</svg>
|
|
54
|
+
`
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { IEditor, IEditorScaleEvent, IEditorRotateEvent, IEditTool, IEditorSkewEvent, IEditorMoveEvent } from '@leafer-in/interface'
|
|
2
|
+
import { LeafHelper } from '@leafer-ui/core'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const { transformWorld, zoomOfWorld, skewOfWorld, rotateOfWorld, moveWorld } = LeafHelper
|
|
6
|
+
|
|
7
|
+
export class EditTool implements IEditTool {
|
|
8
|
+
|
|
9
|
+
static list: IEditTool[] = []
|
|
10
|
+
|
|
11
|
+
public tag = 'EditTool'
|
|
12
|
+
|
|
13
|
+
onMove(e: IEditorMoveEvent): void {
|
|
14
|
+
const { moveX, moveY, editor } = e
|
|
15
|
+
const { app, list } = editor
|
|
16
|
+
app.lockLayout()
|
|
17
|
+
list.forEach(target => {
|
|
18
|
+
moveWorld(target, moveX, moveY)
|
|
19
|
+
})
|
|
20
|
+
app.unlockLayout()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
onScale(e: IEditorScaleEvent): void {
|
|
24
|
+
const { scaleX, scaleY, transform, worldOrigin, editor } = e
|
|
25
|
+
const { app, list } = editor
|
|
26
|
+
app.lockLayout()
|
|
27
|
+
list.forEach(target => {
|
|
28
|
+
const resize = editor.getEditSize(target) === 'size'
|
|
29
|
+
if (transform) {
|
|
30
|
+
transformWorld(target, transform, resize)
|
|
31
|
+
} else {
|
|
32
|
+
zoomOfWorld(target, worldOrigin, scaleX, scaleY, resize)
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
app.unlockLayout()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
onRotate(e: IEditorRotateEvent): void {
|
|
39
|
+
const { rotation, transform, worldOrigin, editor } = e
|
|
40
|
+
const { app, list } = editor
|
|
41
|
+
app.lockLayout()
|
|
42
|
+
list.forEach(target => {
|
|
43
|
+
const resize = editor.getEditSize(target) === 'size'
|
|
44
|
+
if (transform) {
|
|
45
|
+
transformWorld(target, transform, resize)
|
|
46
|
+
} else {
|
|
47
|
+
rotateOfWorld(target, worldOrigin, rotation)
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
app.unlockLayout()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
onSkew(e: IEditorSkewEvent): void {
|
|
54
|
+
const { skewX, skewY, transform, worldOrigin, editor } = e
|
|
55
|
+
const { app, list } = editor
|
|
56
|
+
app.lockLayout()
|
|
57
|
+
list.forEach(target => {
|
|
58
|
+
const resize = editor.getEditSize(target) === 'size'
|
|
59
|
+
if (transform) {
|
|
60
|
+
transformWorld(target, transform, resize)
|
|
61
|
+
} else {
|
|
62
|
+
skewOfWorld(target, worldOrigin, skewX, skewY, resize)
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
app.unlockLayout()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
update(editor: IEditor) {
|
|
69
|
+
const { simulateTarget, element } = editor
|
|
70
|
+
|
|
71
|
+
if (editor.multiple) simulateTarget.parent.updateLayout()
|
|
72
|
+
|
|
73
|
+
const { x, y, scaleX, scaleY, rotation, skewX, skewY, width, height } = element.getLayoutBounds('box', editor, true)
|
|
74
|
+
editor.editBox.set({ x, y, scaleX, scaleY, rotation, skewX, skewY })
|
|
75
|
+
editor.editBox.update({ x: 0, y: 0, width, height })
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
}
|