@leafer-in/editor 1.0.0-rc.9 → 1.0.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/dist/editor.cjs +2008 -0
- package/dist/editor.esm.js +1197 -458
- package/dist/editor.esm.min.js +1 -1
- package/dist/editor.js +1235 -487
- package/dist/editor.min.cjs +1 -0
- package/dist/editor.min.js +1 -1
- package/package.json +12 -7
- package/src/Editor.ts +268 -76
- package/src/config.ts +14 -4
- package/src/decorator/data.ts +1 -1
- package/src/display/EditBox.ts +164 -81
- package/src/display/EditMask.ts +37 -0
- package/src/display/EditPoint.ts +3 -3
- package/src/display/EditSelect.ts +84 -49
- package/src/display/SelectArea.ts +1 -1
- package/src/display/Stroker.ts +24 -21
- package/src/editor/cursor.ts +29 -38
- package/src/editor/simulate.ts +2 -2
- package/src/editor/target.ts +4 -2
- package/src/event/EditorEvent.ts +8 -1
- package/src/event/EditorGroupEvent.ts +23 -0
- package/src/event/EditorScaleEvent.ts +3 -2
- package/src/event/InnerEditorEvent.ts +23 -0
- package/src/helper/EditDataHelper.ts +112 -41
- package/src/helper/EditSelectHelper.ts +5 -4
- package/src/helper/EditorHelper.ts +11 -4
- package/src/index.ts +29 -5
- package/src/svg.ts +54 -0
- package/src/tool/EditTool.ts +51 -22
- package/src/tool/EditToolCreator.ts +32 -0
- package/src/tool/InnerEditor.ts +68 -0
- package/src/tool/LineEditTool.ts +94 -38
- package/types/index.d.ts +157 -52
- package/src/tool/index.ts +0 -21
|
@@ -1,128 +1,173 @@
|
|
|
1
|
-
import { IBoundsData, IPointData, IAround } from '@leafer-ui/interface'
|
|
2
|
-
import { AroundHelper, PointHelper } from '@leafer-ui/
|
|
1
|
+
import { IBoundsData, IPointData, IAround, IAlign, IUI, ILayoutBoundsData } from '@leafer-ui/interface'
|
|
2
|
+
import { AroundHelper, MathHelper, PointHelper, Direction9 } from '@leafer-ui/draw'
|
|
3
3
|
|
|
4
|
-
import { IEditorScaleEvent,
|
|
4
|
+
import { IEditorScaleEvent, IEditorSkewEvent, IEditorRotateEvent } from '@leafer-in/interface'
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
const { topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left } =
|
|
7
|
+
const { topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left } = Direction9
|
|
8
8
|
const { toPoint } = AroundHelper
|
|
9
|
+
const { within } = MathHelper
|
|
9
10
|
|
|
10
11
|
export const EditDataHelper = {
|
|
11
12
|
|
|
12
|
-
getScaleData(
|
|
13
|
-
let
|
|
14
|
-
|
|
13
|
+
getScaleData(element: IUI, startBounds: ILayoutBoundsData, direction: Direction9, totalMove: IPointData, lockRatio: boolean | 'corner', around: IAround, flipable: boolean, scaleMode: boolean): IEditorScaleEvent {
|
|
14
|
+
let align: IAlign, origin = {} as IPointData, scaleX: number = 1, scaleY: number = 1
|
|
15
|
+
|
|
16
|
+
const { boxBounds, widthRange, heightRange } = element
|
|
17
|
+
const { width, height } = startBounds
|
|
15
18
|
|
|
16
19
|
if (around) {
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
totalMove.x *= 2
|
|
21
|
+
totalMove.y *= 2
|
|
19
22
|
}
|
|
20
23
|
|
|
24
|
+
|
|
25
|
+
// 获取已经改变的比例
|
|
26
|
+
const originChangedScaleX = element.scaleX / startBounds.scaleX
|
|
27
|
+
const originChangedScaleY = element.scaleY / startBounds.scaleY
|
|
28
|
+
const signX = originChangedScaleX < 0 ? -1 : 1
|
|
29
|
+
const signY = originChangedScaleY < 0 ? -1 : 1
|
|
30
|
+
|
|
31
|
+
const changedScaleX = scaleMode ? originChangedScaleX : signX * boxBounds.width / width
|
|
32
|
+
const changedScaleY = scaleMode ? originChangedScaleY : signY * boxBounds.height / height
|
|
33
|
+
|
|
34
|
+
totalMove.x *= scaleMode ? originChangedScaleX : signX
|
|
35
|
+
totalMove.y *= scaleMode ? originChangedScaleY : signY
|
|
36
|
+
|
|
37
|
+
|
|
21
38
|
// 防止变为0
|
|
22
|
-
if (Math.abs(
|
|
23
|
-
if (Math.abs(
|
|
39
|
+
if (Math.abs(totalMove.x) === width) totalMove.x += 0.1
|
|
40
|
+
if (Math.abs(totalMove.y) === height) totalMove.y += 0.1
|
|
41
|
+
|
|
24
42
|
|
|
25
|
-
const topScale = (-
|
|
26
|
-
const rightScale = (
|
|
27
|
-
const bottomScale = (
|
|
28
|
-
const leftScale = (-
|
|
43
|
+
const topScale = (-totalMove.y + height) / height
|
|
44
|
+
const rightScale = (totalMove.x + width) / width
|
|
45
|
+
const bottomScale = (totalMove.y + height) / height
|
|
46
|
+
const leftScale = (-totalMove.x + width) / width
|
|
29
47
|
|
|
30
48
|
switch (direction) {
|
|
31
49
|
case top:
|
|
32
50
|
scaleY = topScale
|
|
33
|
-
|
|
51
|
+
align = 'bottom'
|
|
34
52
|
break
|
|
35
53
|
case right:
|
|
36
54
|
scaleX = rightScale
|
|
37
|
-
|
|
55
|
+
align = 'left'
|
|
38
56
|
break
|
|
39
57
|
case bottom:
|
|
40
58
|
scaleY = bottomScale
|
|
41
|
-
|
|
59
|
+
align = 'top'
|
|
42
60
|
break
|
|
43
61
|
case left:
|
|
44
62
|
scaleX = leftScale
|
|
45
|
-
|
|
63
|
+
align = 'right'
|
|
46
64
|
break
|
|
47
65
|
case topLeft:
|
|
48
66
|
scaleY = topScale
|
|
49
67
|
scaleX = leftScale
|
|
50
|
-
|
|
68
|
+
align = 'bottom-right'
|
|
51
69
|
break
|
|
52
70
|
case topRight:
|
|
53
71
|
scaleY = topScale
|
|
54
72
|
scaleX = rightScale
|
|
55
|
-
|
|
73
|
+
align = 'bottom-left'
|
|
56
74
|
break
|
|
57
75
|
case bottomRight:
|
|
58
76
|
scaleY = bottomScale
|
|
59
77
|
scaleX = rightScale
|
|
60
|
-
|
|
78
|
+
align = 'top-left'
|
|
61
79
|
break
|
|
62
80
|
case bottomLeft:
|
|
63
81
|
scaleY = bottomScale
|
|
64
82
|
scaleX = leftScale
|
|
65
|
-
|
|
83
|
+
align = 'top-right'
|
|
66
84
|
}
|
|
67
85
|
|
|
68
86
|
if (lockRatio) {
|
|
69
|
-
|
|
70
|
-
|
|
87
|
+
const unlockSide = lockRatio === 'corner' && direction % 2
|
|
88
|
+
if (!unlockSide) {
|
|
89
|
+
const scale = Math.sqrt(Math.abs(scaleX * scaleY))
|
|
90
|
+
scaleX = scaleX < 0 ? -scale : scale
|
|
91
|
+
scaleY = scaleY < 0 ? -scale : scale
|
|
92
|
+
}
|
|
71
93
|
}
|
|
72
94
|
|
|
73
|
-
|
|
95
|
+
|
|
96
|
+
scaleX /= changedScaleX
|
|
97
|
+
scaleY /= changedScaleY
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
if (!flipable) {
|
|
101
|
+
const { worldTransform } = element
|
|
102
|
+
if (scaleX < 0) scaleX = 1 / boxBounds.width / worldTransform.scaleX
|
|
103
|
+
if (scaleY < 0) scaleY = 1 / boxBounds.height / worldTransform.scaleY
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
if (widthRange) {
|
|
108
|
+
const nowWidth = boxBounds.width * element.scaleX
|
|
109
|
+
scaleX = within(nowWidth * scaleX, widthRange) / nowWidth
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (heightRange) {
|
|
113
|
+
const nowHeight = boxBounds.height * element.scaleY
|
|
114
|
+
scaleY = within(nowHeight * scaleY, heightRange) / nowHeight
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
toPoint(around || align, boxBounds, origin)
|
|
74
119
|
|
|
75
120
|
return { origin, scaleX, scaleY, direction, lockRatio, around }
|
|
76
121
|
},
|
|
77
122
|
|
|
78
|
-
getRotateData(bounds: IBoundsData, direction:
|
|
79
|
-
let
|
|
123
|
+
getRotateData(bounds: IBoundsData, direction: Direction9, current: IPointData, last: IPointData, around: IAround): IEditorRotateEvent {
|
|
124
|
+
let align: IAlign, origin = {} as IPointData
|
|
80
125
|
|
|
81
126
|
switch (direction) {
|
|
82
127
|
case topLeft:
|
|
83
|
-
|
|
128
|
+
align = 'bottom-right'
|
|
84
129
|
break
|
|
85
130
|
case topRight:
|
|
86
|
-
|
|
131
|
+
align = 'bottom-left'
|
|
87
132
|
break
|
|
88
133
|
case bottomRight:
|
|
89
|
-
|
|
134
|
+
align = 'top-left'
|
|
90
135
|
break
|
|
91
136
|
case bottomLeft:
|
|
92
|
-
|
|
137
|
+
align = 'top-right'
|
|
93
138
|
break
|
|
94
139
|
default:
|
|
95
|
-
|
|
140
|
+
align = 'center'
|
|
96
141
|
}
|
|
97
142
|
|
|
98
|
-
toPoint(around ||
|
|
143
|
+
toPoint(around || align, bounds, origin)
|
|
99
144
|
|
|
100
145
|
return { origin, rotation: PointHelper.getRotation(last, origin, current) }
|
|
101
146
|
},
|
|
102
147
|
|
|
103
|
-
getSkewData(bounds: IBoundsData, direction:
|
|
104
|
-
let
|
|
148
|
+
getSkewData(bounds: IBoundsData, direction: Direction9, move: IPointData, around: IAround): IEditorSkewEvent {
|
|
149
|
+
let align: IAlign, origin = {} as IPointData, skewX = 0, skewY = 0
|
|
105
150
|
let last: IPointData
|
|
106
151
|
|
|
107
152
|
switch (direction) {
|
|
108
153
|
case top:
|
|
109
154
|
last = { x: 0.5, y: 0 }
|
|
110
|
-
|
|
155
|
+
align = 'bottom'
|
|
111
156
|
skewX = 1
|
|
112
157
|
break
|
|
113
158
|
case bottom:
|
|
114
159
|
last = { x: 0.5, y: 1 }
|
|
115
|
-
|
|
160
|
+
align = 'top'
|
|
116
161
|
skewX = 1
|
|
117
162
|
break
|
|
118
163
|
case left:
|
|
119
164
|
last = { x: 0, y: 0.5 }
|
|
120
|
-
|
|
165
|
+
align = 'right'
|
|
121
166
|
skewY = 1
|
|
122
167
|
break
|
|
123
168
|
case right:
|
|
124
169
|
last = { x: 1, y: 0.5 }
|
|
125
|
-
|
|
170
|
+
align = 'left'
|
|
126
171
|
skewY = 1
|
|
127
172
|
}
|
|
128
173
|
|
|
@@ -131,7 +176,7 @@ export const EditDataHelper = {
|
|
|
131
176
|
last.x = x + last.x * width
|
|
132
177
|
last.y = y + last.y * height
|
|
133
178
|
|
|
134
|
-
toPoint(around ||
|
|
179
|
+
toPoint(around || align, bounds, origin)
|
|
135
180
|
|
|
136
181
|
const rotation = PointHelper.getRotation(last, origin, { x: last.x + (skewX ? move.x : 0), y: last.y + (skewY ? move.y : 0) })
|
|
137
182
|
skewX ? skewX = -rotation : skewY = rotation
|
|
@@ -147,6 +192,32 @@ export const EditDataHelper = {
|
|
|
147
192
|
getRotateDirection(direction: number, rotation: number, totalDirection = 8): number {
|
|
148
193
|
direction = (direction + Math.round(rotation / (360 / totalDirection))) % totalDirection
|
|
149
194
|
if (direction < 0) direction += totalDirection
|
|
195
|
+
return direction
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
getFlipDirection(direction: Direction9, flipedX: boolean, flipedY: boolean): Direction9 {
|
|
199
|
+
if (flipedX) {
|
|
200
|
+
switch (direction) {
|
|
201
|
+
case left: direction = right; break
|
|
202
|
+
case topLeft: direction = topRight; break
|
|
203
|
+
case bottomLeft: direction = bottomRight; break
|
|
204
|
+
case right: direction = left; break
|
|
205
|
+
case topRight: direction = topLeft; break
|
|
206
|
+
case bottomRight: direction = bottomLeft; break
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (flipedY) {
|
|
211
|
+
switch (direction) {
|
|
212
|
+
case top: direction = bottom; break
|
|
213
|
+
case topLeft: direction = bottomLeft; break
|
|
214
|
+
case topRight: direction = bottomRight; break
|
|
215
|
+
case bottom: direction = top; break
|
|
216
|
+
case bottomLeft: direction = topLeft; break
|
|
217
|
+
case bottomRight: direction = topRight; break
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
150
221
|
return direction
|
|
151
222
|
}
|
|
152
223
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IBounds, ILeafList, IUI } from '@leafer-ui/interface'
|
|
2
|
+
import { Answer } from '@leafer-ui/draw'
|
|
2
3
|
|
|
3
|
-
const { No, Yes, NoAndSkip, YesAndSkip } =
|
|
4
|
+
const { No, Yes, NoAndSkip, YesAndSkip } = Answer
|
|
4
5
|
|
|
5
6
|
export const EditSelectHelper = {
|
|
6
7
|
|
|
@@ -8,8 +9,8 @@ export const EditSelectHelper = {
|
|
|
8
9
|
return path.list.find((leaf) => leaf.editable) as IUI
|
|
9
10
|
},
|
|
10
11
|
|
|
11
|
-
findBounds(leaf: IUI, bounds: IBounds):
|
|
12
|
-
if (leaf.__.hittable && !leaf.__.locked && bounds.hit(leaf.__world)) {
|
|
12
|
+
findBounds(leaf: IUI, bounds: IBounds): Answer {
|
|
13
|
+
if (leaf.__.hittable && leaf.__.visible && !leaf.__.locked && bounds.hit(leaf.__world)) {
|
|
13
14
|
|
|
14
15
|
if (leaf.__.editable) {
|
|
15
16
|
if (leaf.isBranch && !leaf.__.hitChildren) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IGroup, ILeaf, IUI } from '@leafer-ui/interface'
|
|
2
|
-
import { Group, Matrix } from '@leafer-ui/
|
|
1
|
+
import { IGroup, IGroupInputData, ILeaf, IUI } from '@leafer-ui/interface'
|
|
2
|
+
import { Group, Matrix } from '@leafer-ui/draw'
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
const order = (a: ILeaf, b: ILeaf) => a.parent.children.indexOf(a) - b.parent.children.indexOf(b)
|
|
@@ -7,10 +7,17 @@ const reverseOrder = (a: ILeaf, b: ILeaf) => b.parent.children.indexOf(b) - a.pa
|
|
|
7
7
|
|
|
8
8
|
export const EditorHelper = {
|
|
9
9
|
|
|
10
|
-
group(list: IUI[], element?: IUI,
|
|
10
|
+
group(list: IUI[], element?: IUI, userGroup?: IGroup | IGroupInputData): IGroup {
|
|
11
11
|
list.sort(reverseOrder)
|
|
12
12
|
const { app, parent } = list[0]
|
|
13
|
-
|
|
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
|
+
|
|
14
21
|
parent.addAt(group, parent.children.indexOf(list[0]))
|
|
15
22
|
list.sort(order)
|
|
16
23
|
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export * from '@leafer-in/resize'
|
|
2
|
+
|
|
1
3
|
export { Editor } from './Editor'
|
|
2
4
|
|
|
3
5
|
export { EditBox } from './display/EditBox'
|
|
@@ -6,23 +8,45 @@ export { EditSelect } from './display/EditSelect'
|
|
|
6
8
|
export { SelectArea } from './display/SelectArea'
|
|
7
9
|
export { Stroker } from './display/Stroker'
|
|
8
10
|
|
|
11
|
+
|
|
9
12
|
export { EditorEvent } from './event/EditorEvent'
|
|
10
13
|
export { EditorMoveEvent } from './event/EditorMoveEvent'
|
|
11
14
|
export { EditorScaleEvent } from './event/EditorScaleEvent'
|
|
12
15
|
export { EditorRotateEvent } from './event/EditorRotateEvent'
|
|
13
16
|
export { EditorSkewEvent } from './event/EditorSkewEvent'
|
|
17
|
+
export { EditorGroupEvent } from './event/EditorGroupEvent'
|
|
18
|
+
export { InnerEditorEvent } from './event/InnerEditorEvent'
|
|
14
19
|
|
|
15
|
-
export {
|
|
20
|
+
export { EditToolCreator, registerEditTool, registerInnerEditor } from './tool/EditToolCreator'
|
|
21
|
+
export { InnerEditor } from './tool/InnerEditor'
|
|
16
22
|
export { EditTool } from './tool/EditTool'
|
|
23
|
+
export { LineEditTool } from './tool/LineEditTool'
|
|
17
24
|
|
|
18
25
|
export { EditorHelper } from './helper/EditorHelper'
|
|
19
26
|
export { EditDataHelper } from './helper/EditDataHelper'
|
|
20
27
|
export { EditSelectHelper } from './helper/EditSelectHelper'
|
|
21
28
|
|
|
22
|
-
import { IEditor, IEditorConfig } from '@leafer-in/interface'
|
|
23
|
-
import { Creator } from '@leafer-ui/
|
|
29
|
+
import { IEditor, IEditorConfig, IEditToolFunction, IEditorConfigFunction } from '@leafer-in/interface'
|
|
30
|
+
import { Creator, UI, defineKey } from '@leafer-ui/draw'
|
|
31
|
+
|
|
24
32
|
import { Editor } from './Editor'
|
|
25
33
|
|
|
26
|
-
Creator.editor = function (options?: IEditorConfig): IEditor {
|
|
27
|
-
|
|
34
|
+
Creator.editor = function (options?: IEditorConfig): IEditor { return new Editor(options) }
|
|
35
|
+
|
|
36
|
+
UI.setEditConfig = function (config: IEditorConfig | IEditorConfigFunction): void {
|
|
37
|
+
defineKey(this.prototype, 'editConfig', {
|
|
38
|
+
get(): IEditorConfig { return typeof config === 'function' ? config(this) : config }
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
UI.setEditOuter = function (toolName: string | IEditToolFunction): void {
|
|
43
|
+
defineKey(this.prototype, 'editOuter', {
|
|
44
|
+
get(): string { return typeof toolName === 'string' ? toolName : toolName(this) }
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
UI.setEditInner = function (editorName: string | IEditToolFunction): void {
|
|
49
|
+
defineKey(this.prototype, 'editInner', {
|
|
50
|
+
get(): string { return typeof editorName === 'string' ? editorName : editorName(this) }
|
|
51
|
+
})
|
|
28
52
|
}
|
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
|
+
`
|
package/src/tool/EditTool.ts
CHANGED
|
@@ -1,70 +1,99 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IEditorScaleEvent, IEditorRotateEvent, IEditTool, IEditorSkewEvent, IEditorMoveEvent } from '@leafer-in/interface'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { registerEditTool, EditToolCreator } from './EditToolCreator'
|
|
4
|
+
import { InnerEditor } from './InnerEditor'
|
|
4
5
|
|
|
5
|
-
static list: IEditTool[] = []
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
@registerEditTool()
|
|
8
|
+
export class EditTool extends InnerEditor implements IEditTool {
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
static registerEditTool() {
|
|
11
|
+
EditToolCreator.register(this)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
public get tag() { return 'EditTool' }
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
// 操作
|
|
19
|
+
|
|
20
|
+
public onMove(e: IEditorMoveEvent): void {
|
|
10
21
|
const { moveX, moveY, editor } = e
|
|
11
22
|
const { app, list } = editor
|
|
12
23
|
app.lockLayout()
|
|
13
24
|
list.forEach(target => {
|
|
14
|
-
|
|
15
|
-
target.move(move.x, move.y)
|
|
25
|
+
target.moveWorld(moveX, moveY)
|
|
16
26
|
})
|
|
17
27
|
app.unlockLayout()
|
|
18
28
|
}
|
|
19
29
|
|
|
20
|
-
onScale(e: IEditorScaleEvent): void {
|
|
30
|
+
public onScale(e: IEditorScaleEvent): void {
|
|
21
31
|
const { scaleX, scaleY, transform, worldOrigin, editor } = e
|
|
22
32
|
const { app, list } = editor
|
|
23
33
|
app.lockLayout()
|
|
24
34
|
list.forEach(target => {
|
|
25
|
-
const resize = editor.getEditSize(target)
|
|
35
|
+
const resize = editor.getEditSize(target) !== 'scale'
|
|
26
36
|
if (transform) {
|
|
27
|
-
target.
|
|
37
|
+
target.transformWorld(transform, resize)
|
|
28
38
|
} else {
|
|
29
|
-
target.
|
|
39
|
+
target.scaleOfWorld(worldOrigin, scaleX, scaleY, resize)
|
|
30
40
|
}
|
|
31
41
|
})
|
|
32
42
|
app.unlockLayout()
|
|
33
43
|
}
|
|
34
44
|
|
|
35
|
-
onRotate(e: IEditorRotateEvent): void {
|
|
36
|
-
const { rotation, worldOrigin, editor } = e
|
|
45
|
+
public onRotate(e: IEditorRotateEvent): void {
|
|
46
|
+
const { rotation, transform, worldOrigin, editor } = e
|
|
37
47
|
const { app, list } = editor
|
|
38
48
|
app.lockLayout()
|
|
39
49
|
list.forEach(target => {
|
|
40
|
-
|
|
50
|
+
const resize = editor.getEditSize(target) !== 'scale'
|
|
51
|
+
if (transform) {
|
|
52
|
+
target.transformWorld(transform, resize)
|
|
53
|
+
} else {
|
|
54
|
+
target.rotateOfWorld(worldOrigin, rotation)
|
|
55
|
+
}
|
|
41
56
|
})
|
|
42
57
|
app.unlockLayout()
|
|
43
58
|
}
|
|
44
59
|
|
|
45
|
-
onSkew(e: IEditorSkewEvent): void {
|
|
60
|
+
public onSkew(e: IEditorSkewEvent): void {
|
|
46
61
|
const { skewX, skewY, transform, worldOrigin, editor } = e
|
|
47
62
|
const { app, list } = editor
|
|
48
63
|
app.lockLayout()
|
|
49
64
|
list.forEach(target => {
|
|
50
|
-
const resize = editor.getEditSize(target)
|
|
65
|
+
const resize = editor.getEditSize(target) !== 'scale'
|
|
51
66
|
if (transform) {
|
|
52
|
-
target.
|
|
67
|
+
target.transformWorld(transform, resize)
|
|
53
68
|
} else {
|
|
54
|
-
target.
|
|
69
|
+
target.skewOfWorld(worldOrigin, skewX, skewY, resize)
|
|
55
70
|
}
|
|
56
71
|
})
|
|
57
72
|
app.unlockLayout()
|
|
58
73
|
}
|
|
59
74
|
|
|
60
|
-
|
|
61
|
-
|
|
75
|
+
// 状态
|
|
76
|
+
|
|
77
|
+
public load(): void {
|
|
78
|
+
this.editBox.view.visible = true
|
|
79
|
+
this.onLoad()
|
|
80
|
+
}
|
|
62
81
|
|
|
82
|
+
public update(): void {
|
|
83
|
+
const { editor, editBox } = this
|
|
84
|
+
|
|
85
|
+
const { simulateTarget, element } = editor
|
|
63
86
|
if (editor.multiple) simulateTarget.parent.updateLayout()
|
|
64
87
|
|
|
65
88
|
const { x, y, scaleX, scaleY, rotation, skewX, skewY, width, height } = element.getLayoutBounds('box', editor, true)
|
|
66
|
-
|
|
67
|
-
|
|
89
|
+
editBox.set({ x, y, scaleX, scaleY, rotation, skewX, skewY })
|
|
90
|
+
editBox.update({ x: 0, y: 0, width, height })
|
|
91
|
+
this.onUpdate()
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public unload(): void {
|
|
95
|
+
this.editBox.view.visible = false
|
|
96
|
+
this.onUnload()
|
|
68
97
|
}
|
|
69
98
|
|
|
70
99
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { IObject } from '@leafer-ui/interface'
|
|
2
|
+
import { Debug } from '@leafer-ui/draw'
|
|
3
|
+
|
|
4
|
+
import { IEditTool, IEditor } from '@leafer-in/interface'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const debug = Debug.get('EditToolCreator')
|
|
8
|
+
|
|
9
|
+
export function registerEditTool() {
|
|
10
|
+
return (target: IObject) => {
|
|
11
|
+
EditToolCreator.register(target)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const registerInnerEditor = registerEditTool
|
|
16
|
+
|
|
17
|
+
export const EditToolCreator = {
|
|
18
|
+
|
|
19
|
+
list: {} as IObject,
|
|
20
|
+
|
|
21
|
+
register(EditTool: IObject): void {
|
|
22
|
+
const { tag } = EditTool.prototype as IEditTool
|
|
23
|
+
list[tag] ? debug.repeat(tag) : (list[tag] = EditTool)
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
get(tag: string, editor: IEditor): IEditTool {
|
|
27
|
+
return new list[tag](editor)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const { list } = EditToolCreator
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { IGroup, IEventListenerId, IUI, IObject } from '@leafer-ui/interface'
|
|
2
|
+
import { IInnerEditor, IEditor, IEditBox } from '@leafer-in/interface'
|
|
3
|
+
|
|
4
|
+
import { Group } from '@leafer-ui/draw'
|
|
5
|
+
import { EditToolCreator } from './EditToolCreator'
|
|
6
|
+
|
|
7
|
+
export class InnerEditor implements IInnerEditor {
|
|
8
|
+
|
|
9
|
+
static registerInnerEditor() {
|
|
10
|
+
EditToolCreator.register(this)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
public get tag() { return 'InnerEditor' }
|
|
15
|
+
|
|
16
|
+
public editTarget: IUI
|
|
17
|
+
|
|
18
|
+
public config: IObject
|
|
19
|
+
|
|
20
|
+
public editor: IEditor
|
|
21
|
+
public get editBox(): IEditBox { return this.editor.editBox }
|
|
22
|
+
|
|
23
|
+
public view: IGroup
|
|
24
|
+
|
|
25
|
+
public eventIds: IEventListenerId[]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
constructor(editor: IEditor) {
|
|
29
|
+
this.editor = editor
|
|
30
|
+
this.create()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
public onCreate(): void { }
|
|
35
|
+
public create(): void {
|
|
36
|
+
this.view = new Group()
|
|
37
|
+
this.onCreate()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
// 状态
|
|
42
|
+
|
|
43
|
+
public onLoad(): void { }
|
|
44
|
+
public load(): void {
|
|
45
|
+
this.editor.selector.hittable = this.editor.app.tree.hitChildren = false
|
|
46
|
+
this.onLoad()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public onUpdate(): void { }
|
|
50
|
+
public update(): void { this.onUpdate() }
|
|
51
|
+
|
|
52
|
+
public onUnload(): void { }
|
|
53
|
+
public unload(): void {
|
|
54
|
+
this.editor.selector.hittable = this.editor.app.tree.hitChildren = true
|
|
55
|
+
this.onUnload()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public onDestroy(): void { }
|
|
59
|
+
public destroy(): void {
|
|
60
|
+
this.onDestroy()
|
|
61
|
+
if (this.editor) {
|
|
62
|
+
if (this.view) this.view.destroy()
|
|
63
|
+
if (this.eventIds) this.editor.off_(this.eventIds)
|
|
64
|
+
this.editor = this.view = this.eventIds = null
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
}
|