@leafer-in/editor 1.0.0-rc.9 → 1.0.0
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 +1937 -0
- package/dist/editor.esm.js +1080 -412
- package/dist/editor.esm.min.js +1 -1
- package/dist/editor.js +1118 -441
- package/dist/editor.min.cjs +1 -0
- package/dist/editor.min.js +1 -1
- package/package.json +12 -7
- package/src/Editor.ts +231 -57
- package/src/config.ts +13 -4
- package/src/decorator/data.ts +1 -1
- package/src/display/EditBox.ts +147 -69
- package/src/display/EditMask.ts +37 -0
- package/src/display/EditPoint.ts +3 -3
- package/src/display/EditSelect.ts +61 -42
- package/src/display/SelectArea.ts +1 -1
- package/src/display/Stroker.ts +24 -21
- package/src/editor/cursor.ts +25 -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 +62 -32
- 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 +147 -49
- package/src/tool/index.ts +0 -21
package/src/display/EditBox.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { IRect,
|
|
2
|
-
import { Group,
|
|
1
|
+
import { IRect, IEventListenerId, IBoundsData, IPointData, IKeyEvent, IGroup, IBox, IBoxInputData, IAlign } from '@leafer-ui/interface'
|
|
2
|
+
import { Group, Box, AroundHelper, Direction9 } from '@leafer-ui/draw'
|
|
3
|
+
import { DragEvent, PointerEvent, RotateEvent, ZoomEvent } from '@leafer-ui/core'
|
|
3
4
|
|
|
4
|
-
import { IEditBox, IEditor,
|
|
5
|
+
import { IEditBox, IEditor, IEditPoint, IEditPointType } from '@leafer-in/interface'
|
|
5
6
|
|
|
6
7
|
import { updateCursor, updateMoveCursor } from '../editor/cursor'
|
|
7
8
|
import { EditorEvent } from '../event/EditorEvent'
|
|
@@ -15,9 +16,12 @@ export class EditBox extends Group implements IEditBox {
|
|
|
15
16
|
|
|
16
17
|
public editor: IEditor
|
|
17
18
|
public dragging: boolean
|
|
19
|
+
public moving: boolean
|
|
20
|
+
|
|
21
|
+
public view: IGroup = new Group() // 放置默认编辑工具控制点
|
|
18
22
|
|
|
19
23
|
public rect: IBox = new Box({ name: 'rect', hitFill: 'all', hitStroke: 'none', strokeAlign: 'center', hitRadius: 5 }) // target rect
|
|
20
|
-
public circle: IEditPoint = new EditPoint({ name: 'circle', strokeAlign: '
|
|
24
|
+
public circle: IEditPoint = new EditPoint({ name: 'circle', strokeAlign: 'center', around: 'center', cursor: 'crosshair', hitRadius: 5 }) // rotate point
|
|
21
25
|
|
|
22
26
|
public buttons: IGroup = new Group({ around: 'center', hitSelf: false })
|
|
23
27
|
|
|
@@ -40,16 +44,17 @@ export class EditBox extends Group implements IEditBox {
|
|
|
40
44
|
this.editor = editor
|
|
41
45
|
this.visible = false
|
|
42
46
|
this.create()
|
|
47
|
+
this.rect.syncEventer = editor // rect的事件不会冒泡,需要手动传递给editor
|
|
43
48
|
this.__listenEvents()
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
public create() {
|
|
47
52
|
let rotatePoint: IEditPoint, resizeLine: IEditPoint, resizePoint: IEditPoint
|
|
48
|
-
const { resizePoints, rotatePoints, resizeLines, rect, circle, buttons } = this
|
|
49
|
-
const arounds:
|
|
53
|
+
const { view, resizePoints, rotatePoints, resizeLines, rect, circle, buttons } = this
|
|
54
|
+
const arounds: IAlign[] = ['bottom-right', 'bottom', 'bottom-left', 'left', 'top-left', 'top', 'top-right', 'right']
|
|
50
55
|
|
|
51
56
|
for (let i = 0; i < 8; i++) {
|
|
52
|
-
rotatePoint = new EditPoint({ around: arounds[i], width: 15, height: 15, hitFill: "all" })
|
|
57
|
+
rotatePoint = new EditPoint({ name: 'rotate-point', around: arounds[i], width: 15, height: 15, hitFill: "all" })
|
|
53
58
|
rotatePoints.push(rotatePoint)
|
|
54
59
|
this.listenPointEvents(rotatePoint, 'rotate', i)
|
|
55
60
|
|
|
@@ -59,7 +64,7 @@ export class EditBox extends Group implements IEditBox {
|
|
|
59
64
|
this.listenPointEvents(resizeLine, 'resize', i)
|
|
60
65
|
}
|
|
61
66
|
|
|
62
|
-
resizePoint = new EditPoint({ name: 'resize-point',
|
|
67
|
+
resizePoint = new EditPoint({ name: 'resize-point', hitRadius: 5 })
|
|
63
68
|
resizePoints.push(resizePoint)
|
|
64
69
|
this.listenPointEvents(resizePoint, 'resize', i)
|
|
65
70
|
}
|
|
@@ -67,69 +72,100 @@ export class EditBox extends Group implements IEditBox {
|
|
|
67
72
|
buttons.add(circle)
|
|
68
73
|
this.listenPointEvents(circle, 'rotate', 2)
|
|
69
74
|
|
|
70
|
-
|
|
75
|
+
view.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints)
|
|
76
|
+
this.add(view)
|
|
71
77
|
}
|
|
72
78
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const {
|
|
77
|
-
const { width, height } = bounds
|
|
78
|
-
const { rect, circle, resizePoints, rotatePoints, resizeLines } = this
|
|
79
|
-
const { middlePoint, resizeable, rotateable, stroke, strokeWidth } = config
|
|
79
|
+
public load(): void {
|
|
80
|
+
const { mergeConfig, element, single } = this.editor
|
|
81
|
+
const { rect, circle, resizePoints } = this
|
|
82
|
+
const { stroke, strokeWidth, moveable } = mergeConfig
|
|
80
83
|
|
|
81
84
|
const pointsStyle = this.getPointsStyle()
|
|
82
85
|
const middlePointsStyle = this.getMiddlePointsStyle()
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
let point = {} as IPointData, style: IRectInputData, rotateP: IRect, resizeP: IRect, resizeL: IRect
|
|
87
|
+
let resizeP: IRect
|
|
87
88
|
|
|
88
89
|
for (let i = 0; i < 8; i++) {
|
|
90
|
+
resizeP = resizePoints[i]
|
|
91
|
+
resizeP.set(this.getPointStyle((i % 2) ? middlePointsStyle[((i - 1) / 2) % middlePointsStyle.length] : pointsStyle[(i / 2) % pointsStyle.length]))
|
|
92
|
+
if (!(i % 2)) resizeP.rotation = (i / 2) * 90
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// rotate
|
|
96
|
+
circle.set(this.getPointStyle(mergeConfig.rotatePoint || pointsStyle[0]))
|
|
97
|
+
|
|
98
|
+
// rect
|
|
99
|
+
rect.set({ stroke, strokeWidth, ...(mergeConfig.rect || {}) })
|
|
100
|
+
rect.hittable = !single && moveable
|
|
89
101
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
resizeP.set(style)
|
|
94
|
-
resizeP.set(point), rotateP.set(point), resizeL.set(point)
|
|
102
|
+
// 编辑框作为底部虚拟元素, 在 onSelect 方法移除
|
|
103
|
+
element.syncEventer = (single && moveable) ? rect : null
|
|
104
|
+
this.app.interaction.bottomList = (single && moveable) ? [{ target: rect, proxy: element }] : null
|
|
95
105
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public update(bounds: IBoundsData): void {
|
|
109
|
+
this.visible = !this.editor.element.locked
|
|
99
110
|
|
|
100
|
-
|
|
111
|
+
if (this.view.worldOpacity) {
|
|
112
|
+
const { mergeConfig } = this.editor
|
|
113
|
+
const { width, height } = bounds
|
|
114
|
+
const { rect, circle, resizePoints, rotatePoints, resizeLines } = this
|
|
115
|
+
const { middlePoint, resizeable, rotateable, hideOnSmall } = mergeConfig
|
|
101
116
|
|
|
102
|
-
|
|
117
|
+
const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10
|
|
118
|
+
const showPoints = !(hideOnSmall && width < smallSize && height < smallSize)
|
|
103
119
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
120
|
+
let point = {} as IPointData, rotateP: IRect, resizeP: IRect, resizeL: IRect
|
|
121
|
+
|
|
122
|
+
for (let i = 0; i < 8; i++) {
|
|
123
|
+
|
|
124
|
+
AroundHelper.toPoint(AroundHelper.directionData[i], bounds, point)
|
|
125
|
+
resizeP = resizePoints[i]
|
|
126
|
+
rotateP = rotatePoints[i]
|
|
127
|
+
resizeL = resizeLines[Math.floor(i / 2)]
|
|
128
|
+
resizeP.set(point)
|
|
129
|
+
rotateP.set(point)
|
|
130
|
+
resizeL.set(point)
|
|
131
|
+
|
|
132
|
+
// visible
|
|
133
|
+
resizeP.visible = resizeL.visible = showPoints && !!(resizeable || rotateable)
|
|
134
|
+
rotateP.visible = showPoints && rotateable && resizeable && !mergeConfig.rotatePoint
|
|
135
|
+
|
|
136
|
+
if (i % 2) { // top, right, bottom, left
|
|
137
|
+
|
|
138
|
+
resizeP.visible = rotateP.visible = showPoints && !!middlePoint
|
|
139
|
+
|
|
140
|
+
if (((i + 1) / 2) % 2) { // top, bottom
|
|
141
|
+
resizeL.width = width
|
|
142
|
+
if (resizeP.width > width - 30) resizeP.visible = false
|
|
143
|
+
} else {
|
|
144
|
+
resizeL.height = height
|
|
145
|
+
resizeP.rotation = 90
|
|
146
|
+
if (resizeP.width > height - 30) resizeP.visible = false
|
|
147
|
+
}
|
|
111
148
|
}
|
|
112
|
-
|
|
113
|
-
resizeP.rotation = (i / 2) * 90
|
|
149
|
+
|
|
114
150
|
}
|
|
115
151
|
|
|
116
|
-
|
|
152
|
+
// rotate
|
|
153
|
+
circle.visible = showPoints && rotateable && !!mergeConfig.rotatePoint
|
|
117
154
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
155
|
+
// rect
|
|
156
|
+
if (rect.path) rect.path = null // line可能会变成path优先模式
|
|
157
|
+
rect.set({ ...bounds, visible: true })
|
|
121
158
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
this.layoutButtons()
|
|
159
|
+
// buttons
|
|
160
|
+
const buttonVisible = showPoints && (circle.visible || this.buttons.children.length > 1)
|
|
161
|
+
this.buttons.visible = buttonVisible
|
|
162
|
+
if (buttonVisible) this.layoutButtons()
|
|
163
|
+
}
|
|
128
164
|
}
|
|
129
165
|
|
|
130
166
|
protected layoutButtons(): void {
|
|
131
167
|
const { buttons, resizePoints } = this
|
|
132
|
-
const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.editor.
|
|
168
|
+
const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.editor.mergeConfig
|
|
133
169
|
|
|
134
170
|
const { flippedX, flippedY } = this
|
|
135
171
|
let index = fourDirection.indexOf(buttonsDirection)
|
|
@@ -161,46 +197,66 @@ export class EditBox extends Group implements IEditBox {
|
|
|
161
197
|
|
|
162
198
|
}
|
|
163
199
|
|
|
164
|
-
public
|
|
165
|
-
|
|
166
|
-
|
|
200
|
+
public unload(): void {
|
|
201
|
+
this.visible = false
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
public getPointStyle(userStyle?: IBoxInputData): IBoxInputData {
|
|
206
|
+
const { stroke, strokeWidth, pointFill, pointSize, pointRadius } = this.editor.mergeConfig
|
|
207
|
+
const defaultStyle = { fill: pointFill, stroke, strokeWidth, around: 'center', strokeAlign: 'center', width: pointSize, height: pointSize, cornerRadius: pointRadius } as IBoxInputData
|
|
167
208
|
return userStyle ? Object.assign(defaultStyle, userStyle) : defaultStyle
|
|
168
209
|
}
|
|
169
210
|
|
|
170
|
-
public getPointsStyle():
|
|
171
|
-
const { point } = this.editor.
|
|
211
|
+
public getPointsStyle(): IBoxInputData[] {
|
|
212
|
+
const { point } = this.editor.mergeConfig
|
|
172
213
|
return point instanceof Array ? point : [point]
|
|
173
214
|
}
|
|
174
215
|
|
|
175
|
-
public getMiddlePointsStyle():
|
|
176
|
-
const { middlePoint } = this.editor.
|
|
216
|
+
public getMiddlePointsStyle(): IBoxInputData[] {
|
|
217
|
+
const { middlePoint } = this.editor.mergeConfig
|
|
177
218
|
return middlePoint instanceof Array ? middlePoint : (middlePoint ? [middlePoint] : this.getPointsStyle())
|
|
178
219
|
}
|
|
179
220
|
|
|
221
|
+
protected onSelect(e: EditorEvent): void {
|
|
222
|
+
if (e.oldList.length === 1) {
|
|
223
|
+
e.oldList[0].syncEventer = null
|
|
224
|
+
if (this.app) this.app.interaction.bottomList = null
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
180
228
|
// drag
|
|
181
229
|
|
|
182
230
|
protected onDragStart(e: DragEvent): void {
|
|
183
231
|
this.dragging = true
|
|
184
|
-
if (e.
|
|
232
|
+
if (e.current.name === 'rect') {
|
|
233
|
+
const { editor } = this
|
|
234
|
+
this.moving = true
|
|
235
|
+
editor.dragStartPoint = { x: editor.element.x, y: editor.element.y }
|
|
236
|
+
editor.opacity = editor.mergeConfig.hideOnMove ? 0 : 1 // move
|
|
237
|
+
}
|
|
185
238
|
}
|
|
186
239
|
|
|
187
240
|
protected onDragEnd(e: DragEvent): void {
|
|
188
241
|
this.dragging = false
|
|
189
|
-
|
|
242
|
+
this.moving = false
|
|
243
|
+
if (e.current.name === 'rect') this.editor.opacity = 1 // move
|
|
244
|
+
|
|
190
245
|
}
|
|
191
246
|
|
|
192
247
|
protected onDrag(e: DragEvent): void {
|
|
193
248
|
const { editor } = this
|
|
194
|
-
const point = e.current as IEditPoint
|
|
195
|
-
if (point.pointType === 'rotate' || e.metaKey || e.ctrlKey || !editor.
|
|
196
|
-
if (editor.
|
|
249
|
+
const point = this.enterPoint = e.current as IEditPoint
|
|
250
|
+
if (point.pointType === 'rotate' || e.metaKey || e.ctrlKey || !editor.mergeConfig.resizeable) {
|
|
251
|
+
if (editor.mergeConfig.rotateable) editor.onRotate(e)
|
|
197
252
|
} else {
|
|
198
253
|
editor.onScale(e)
|
|
199
254
|
}
|
|
255
|
+
updateCursor(editor, e)
|
|
200
256
|
}
|
|
201
257
|
|
|
202
258
|
public onArrow(e: IKeyEvent): void {
|
|
203
|
-
if (this.editor.
|
|
259
|
+
if (this.editor.editing && this.editor.mergeConfig.keyEvent) {
|
|
204
260
|
const move = { x: 0, y: 0 }
|
|
205
261
|
const distance = e.shiftKey ? 10 : 1
|
|
206
262
|
switch (e.code) {
|
|
@@ -216,18 +272,34 @@ export class EditBox extends Group implements IEditBox {
|
|
|
216
272
|
case 'ArrowRight':
|
|
217
273
|
move.x = distance
|
|
218
274
|
}
|
|
219
|
-
|
|
275
|
+
this.editor.move(move)
|
|
220
276
|
}
|
|
221
277
|
}
|
|
222
278
|
|
|
223
|
-
|
|
279
|
+
|
|
280
|
+
protected onDoubleTap(e: PointerEvent): void {
|
|
281
|
+
if (this.editor.mergeConfig.openInner === 'double') this.openInner(e)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
protected onLongPress(e: PointerEvent): void {
|
|
285
|
+
if (this.editor.mergeConfig.openInner === 'long') this.openInner(e)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
protected openInner(e: PointerEvent): void {
|
|
224
289
|
const { editor } = this
|
|
225
|
-
if (editor.single
|
|
226
|
-
|
|
290
|
+
if (editor.single) {
|
|
291
|
+
const { element } = editor
|
|
292
|
+
if (element.isBranch) {
|
|
293
|
+
editor.openGroup(element as IGroup)
|
|
294
|
+
editor.target = editor.selector.findDeepOne(e)
|
|
295
|
+
} else {
|
|
296
|
+
editor.openInnerEditor()
|
|
297
|
+
}
|
|
227
298
|
}
|
|
228
299
|
}
|
|
229
300
|
|
|
230
|
-
|
|
301
|
+
|
|
302
|
+
public listenPointEvents(point: IEditPoint, type: IEditPointType, direction: Direction9): void {
|
|
231
303
|
const { editor } = this
|
|
232
304
|
point.direction = direction
|
|
233
305
|
point.pointType = type
|
|
@@ -241,12 +313,18 @@ export class EditBox extends Group implements IEditBox {
|
|
|
241
313
|
protected __listenEvents(): void {
|
|
242
314
|
const { rect, editor } = this
|
|
243
315
|
this.__eventIds = [
|
|
244
|
-
editor.on_(EditorEvent.SELECT,
|
|
316
|
+
editor.on_(EditorEvent.SELECT, this.onSelect, this),
|
|
317
|
+
|
|
245
318
|
rect.on_(DragEvent.START, this.onDragStart, this),
|
|
246
319
|
rect.on_(DragEvent.DRAG, editor.onMove, editor),
|
|
247
320
|
rect.on_(DragEvent.END, this.onDragEnd, this),
|
|
321
|
+
|
|
322
|
+
rect.on_(ZoomEvent.BEFORE_ZOOM, editor.onScale, editor, true),
|
|
323
|
+
rect.on_(RotateEvent.BEFORE_ROTATE, editor.onRotate, editor, true),
|
|
324
|
+
|
|
248
325
|
rect.on_(PointerEvent.ENTER, () => updateMoveCursor(editor)),
|
|
249
|
-
rect.on_(PointerEvent.
|
|
326
|
+
rect.on_(PointerEvent.DOUBLE_TAP, this.onDoubleTap, this),
|
|
327
|
+
rect.on_(PointerEvent.LONG_PRESS, this.onLongPress, this)
|
|
250
328
|
]
|
|
251
329
|
}
|
|
252
330
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ILeaferCanvas, IRenderOptions } from '@leafer-ui/interface'
|
|
2
|
+
import { UI } from '@leafer-ui/draw'
|
|
3
|
+
|
|
4
|
+
import { IEditor } from '@leafer-in/interface'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export class EditMask extends UI {
|
|
8
|
+
|
|
9
|
+
public editor: IEditor
|
|
10
|
+
|
|
11
|
+
constructor(editor: IEditor) {
|
|
12
|
+
super()
|
|
13
|
+
this.editor = editor
|
|
14
|
+
this.hittable = false
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public __draw(canvas: ILeaferCanvas, options: IRenderOptions): void {
|
|
18
|
+
const { editor } = this
|
|
19
|
+
const { mask } = editor.mergeConfig
|
|
20
|
+
|
|
21
|
+
if (mask && editor.list.length) {
|
|
22
|
+
const { rect } = editor.editBox
|
|
23
|
+
const { width, height } = rect.__
|
|
24
|
+
|
|
25
|
+
canvas.resetTransform()
|
|
26
|
+
canvas.fillWorld(canvas.bounds, mask)
|
|
27
|
+
canvas.setWorld(rect.__world, options.matrix)
|
|
28
|
+
canvas.clearRect(0, 0, width, height)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public destroy(): void {
|
|
33
|
+
this.editor = null
|
|
34
|
+
super.destroy()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
}
|
package/src/display/EditPoint.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Box } from '@leafer-ui/
|
|
1
|
+
import { Box, Direction9 } from '@leafer-ui/draw'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { IEditPoint, IEditPointType } from '@leafer-in/interface'
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
export class EditPoint extends Box implements IEditPoint {
|
|
7
|
-
public direction:
|
|
7
|
+
public direction: Direction9
|
|
8
8
|
public pointType: IEditPointType
|
|
9
9
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { IBounds, ILeaf, ILeafList, IUI, IEventListenerId } from '@leafer-ui/interface'
|
|
2
|
-
import { Bounds,
|
|
1
|
+
import { IBounds, ILeaf, ILeafList, IUI, IEventListenerId, IPointerEvent } from '@leafer-ui/interface'
|
|
2
|
+
import { Bounds, LeafList, Group } from '@leafer-ui/draw'
|
|
3
|
+
import { PointerEvent, DragEvent, MoveEvent, ZoomEvent } from '@leafer-ui/core'
|
|
3
4
|
|
|
4
5
|
import { IEditSelect, IEditor, ISelectArea, IStroker } from '@leafer-in/interface'
|
|
5
6
|
|
|
@@ -16,7 +17,7 @@ export class EditSelect extends Group implements IEditSelect {
|
|
|
16
17
|
public editor: IEditor
|
|
17
18
|
|
|
18
19
|
public get dragging(): boolean { return !!this.originList }
|
|
19
|
-
public get running(): boolean { return this.editor.hittable &&
|
|
20
|
+
public get running(): boolean { const { editor } = this; return this.hittable && editor.visible && editor.hittable && editor.mergeConfig.selector }
|
|
20
21
|
public get isMoveMode(): boolean { return this.app && this.app.interaction.moveMode }
|
|
21
22
|
|
|
22
23
|
public hoverStroker: IStroker = new Stroker()
|
|
@@ -26,7 +27,7 @@ export class EditSelect extends Group implements IEditSelect {
|
|
|
26
27
|
public selectArea: ISelectArea = new SelectArea()
|
|
27
28
|
|
|
28
29
|
protected originList: ILeafList
|
|
29
|
-
protected
|
|
30
|
+
protected needRemoveItem: IUI
|
|
30
31
|
|
|
31
32
|
protected __eventIds: IEventListenerId[] = []
|
|
32
33
|
|
|
@@ -43,8 +44,8 @@ export class EditSelect extends Group implements IEditSelect {
|
|
|
43
44
|
protected onHover(): void {
|
|
44
45
|
const { editor } = this
|
|
45
46
|
if (this.running && !this.dragging && !editor.dragging) {
|
|
46
|
-
const { stroke, strokeWidth, hover } = editor.
|
|
47
|
-
this.hoverStroker.setTarget(hover ? this.editor.hoverTarget : null, { stroke, strokeWidth })
|
|
47
|
+
const { stroke, strokeWidth, hover, hoverStyle } = editor.mergeConfig
|
|
48
|
+
this.hoverStroker.setTarget(hover ? this.editor.hoverTarget : null, { stroke, strokeWidth, ...(hoverStyle || {}) })
|
|
48
49
|
} else {
|
|
49
50
|
this.hoverStroker.target = null
|
|
50
51
|
}
|
|
@@ -52,7 +53,7 @@ export class EditSelect extends Group implements IEditSelect {
|
|
|
52
53
|
|
|
53
54
|
protected onSelect(): void {
|
|
54
55
|
if (this.running) {
|
|
55
|
-
const { config, list } = this.editor
|
|
56
|
+
const { mergeConfig: config, list } = this.editor
|
|
56
57
|
const { stroke, strokeWidth } = config
|
|
57
58
|
this.targetStroker.setTarget(list, { stroke, strokeWidth: Math.max(1, strokeWidth / 2) })
|
|
58
59
|
this.hoverStroker.target = null
|
|
@@ -60,66 +61,73 @@ export class EditSelect extends Group implements IEditSelect {
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
public update(): void {
|
|
63
|
-
if (this.
|
|
64
|
+
if (this.targetStroker.target) this.targetStroker.forceUpdate()
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
// move / down
|
|
67
68
|
|
|
68
69
|
protected onPointerMove(e: PointerEvent): void {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
const { app, editor } = this
|
|
71
|
+
if (this.running && !this.isMoveMode && app.config.pointer.hover && !app.interaction.dragging) {
|
|
72
|
+
const find = this.findUI(e)
|
|
73
|
+
editor.hoverTarget = editor.hasItem(find) ? null : find
|
|
72
74
|
} if (this.isMoveMode) {
|
|
73
|
-
|
|
75
|
+
editor.hoverTarget = null // move.dragEmpty
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
protected onBeforeDown(e: PointerEvent): void {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
const { select } = this.editor.mergeConfig
|
|
81
|
+
if (select === 'press') this.checkAndSelect(e)
|
|
82
|
+
}
|
|
80
83
|
|
|
81
|
-
|
|
84
|
+
protected onTap(e: PointerEvent): void {
|
|
85
|
+
const { editor } = this
|
|
86
|
+
const { select } = editor.mergeConfig
|
|
87
|
+
if (select === 'tap') this.checkAndSelect(e)
|
|
88
|
+
|
|
89
|
+
if (this.needRemoveItem) {
|
|
90
|
+
editor.removeItem(this.needRemoveItem)
|
|
91
|
+
} else if (this.isMoveMode) {
|
|
92
|
+
editor.target = null // move.dragEmpty
|
|
93
|
+
}
|
|
82
94
|
|
|
83
|
-
|
|
84
|
-
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
protected checkAndSelect(e: PointerEvent): void { // pointer.down or tap
|
|
98
|
+
this.needRemoveItem = null
|
|
99
|
+
|
|
100
|
+
if (this.allowSelect(e)) {
|
|
101
|
+
const { editor } = this
|
|
102
|
+
const find = this.findUI(e)
|
|
103
|
+
|
|
104
|
+
if (find) {
|
|
105
|
+
if (this.isMultipleSelect(e)) {
|
|
106
|
+
if (editor.hasItem(find)) this.needRemoveItem = find // 等待tap事件再实际移除
|
|
107
|
+
else editor.addItem(find)
|
|
85
108
|
} else {
|
|
86
|
-
|
|
109
|
+
editor.target = find
|
|
87
110
|
}
|
|
88
111
|
|
|
89
|
-
// change down data
|
|
90
|
-
this.editor.updateLayout()
|
|
91
|
-
find.leafer.interaction.updateDownData()
|
|
92
|
-
|
|
93
112
|
} else if (this.allow(e.target)) {
|
|
94
113
|
|
|
95
|
-
if (!e.shiftKey)
|
|
114
|
+
if (!e.shiftKey) editor.target = null
|
|
96
115
|
|
|
97
116
|
}
|
|
98
117
|
}
|
|
99
118
|
}
|
|
100
119
|
|
|
101
|
-
protected onTap(e: PointerEvent): void {
|
|
102
|
-
if (this.running && e.shiftKey && !e.middle && !this.lastDownLeaf) {
|
|
103
|
-
const find = this.findDeepOne(e)
|
|
104
|
-
if (find) this.editor.shiftItem(find)
|
|
105
|
-
} else if (this.isMoveMode) {
|
|
106
|
-
this.editor.target = null // move.dragEmpty
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
this.lastDownLeaf = null
|
|
110
|
-
}
|
|
111
|
-
|
|
112
120
|
// drag
|
|
113
121
|
|
|
114
122
|
protected onDragStart(e: DragEvent): void {
|
|
115
|
-
if (this.
|
|
123
|
+
if (this.allowDrag(e)) {
|
|
116
124
|
const { editor } = this
|
|
117
|
-
const { stroke,
|
|
125
|
+
const { stroke, area } = editor.mergeConfig
|
|
118
126
|
const { x, y } = e.getInner(this)
|
|
119
127
|
|
|
120
128
|
this.bounds.set(x, y)
|
|
121
129
|
|
|
122
|
-
this.selectArea.setStyle({ visible: true, stroke,
|
|
130
|
+
this.selectArea.setStyle({ visible: true, stroke, x, y }, area)
|
|
123
131
|
this.selectArea.setBounds(this.bounds.get())
|
|
124
132
|
|
|
125
133
|
this.originList = editor.leafList.clone()
|
|
@@ -158,7 +166,6 @@ export class EditSelect extends Group implements IEditSelect {
|
|
|
158
166
|
} else {
|
|
159
167
|
|
|
160
168
|
editor.target = this.originList.list as IUI[]
|
|
161
|
-
if (editor.leafList.length) editor.update()
|
|
162
169
|
|
|
163
170
|
}
|
|
164
171
|
}
|
|
@@ -183,18 +190,30 @@ export class EditSelect extends Group implements IEditSelect {
|
|
|
183
190
|
}
|
|
184
191
|
|
|
185
192
|
protected allowDrag(e: DragEvent) {
|
|
186
|
-
if (this.editor.
|
|
187
|
-
return (!this.editor.
|
|
193
|
+
if (this.running && this.editor.mergeConfig.boxSelect && !e.target.draggable) {
|
|
194
|
+
return (!this.editor.editing && this.allow(e.target)) || (e.shiftKey && !findOne(e.path))
|
|
188
195
|
} else {
|
|
189
196
|
return false
|
|
190
197
|
}
|
|
191
198
|
}
|
|
192
199
|
|
|
193
|
-
protected
|
|
200
|
+
protected allowSelect(e: IPointerEvent): boolean {
|
|
201
|
+
return this.running && !this.isMoveMode && !e.middle
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public findDeepOne(e: PointerEvent): IUI {
|
|
194
205
|
const options = { exclude: new LeafList(this.editor.editBox.rect) }
|
|
195
206
|
return findOne(e.target.leafer.interaction.findPath(e, options)) as IUI
|
|
196
207
|
}
|
|
197
208
|
|
|
209
|
+
public findUI(e: PointerEvent): IUI {
|
|
210
|
+
return this.isMultipleSelect(e) ? this.findDeepOne(e) : findOne(e.path)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
public isMultipleSelect(e: IPointerEvent): boolean {
|
|
214
|
+
return e.shiftKey || this.editor.mergeConfig.continuousSelect
|
|
215
|
+
}
|
|
216
|
+
|
|
198
217
|
protected __listenEvents(): void {
|
|
199
218
|
const { editor } = this
|
|
200
219
|
editor.waitLeafer(() => {
|
|
@@ -229,7 +248,7 @@ export class EditSelect extends Group implements IEditSelect {
|
|
|
229
248
|
}
|
|
230
249
|
|
|
231
250
|
public destroy(): void {
|
|
232
|
-
this.editor = this.originList = this.
|
|
251
|
+
this.editor = this.originList = this.needRemoveItem = null
|
|
233
252
|
this.__removeListenEvents()
|
|
234
253
|
super.destroy()
|
|
235
254
|
}
|