@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.
@@ -1,7 +1,8 @@
1
- import { IRect, IAround, IEventListenerId, IBoundsData, IRectInputData, IPointData, IKeyEvent, IGroup, IBox } from '@leafer-ui/interface'
2
- import { Group, DragEvent, PointerEvent, Box, AroundHelper } from '@leafer-ui/core'
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, IDirection8, IEditPoint, IEditPointType } from '@leafer-in/interface'
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: 'outside', around: 'center', cursor: 'crosshair', hitRadius: 5 }) // rotate point
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: IAround[] = [{ x: 1, y: 1 }, { x: 0.5, y: 1 }, { x: 0, y: 1 }, { x: 0, y: 0.5 }, { x: 0, y: 0 }, { x: 0.5, y: 0 }, { x: 1, y: 0 }, { x: 1, y: 0.5 }]
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', around: 'center', strokeAlign: 'outside', hitRadius: 5 })
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
- this.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints)
75
+ view.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints)
76
+ this.add(view)
71
77
  }
72
78
 
73
- // update
74
-
75
- public update(bounds: IBoundsData): void {
76
- const { config, list } = this.editor
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
- this.visible = list[0] && !list[0].locked // check locked
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
- AroundHelper.toPoint(AroundHelper.directionData[i], bounds, point)
91
- style = this.getPointStyle((i % 2) ? middlePointsStyle[((i - 1) / 2) % middlePointsStyle.length] : pointsStyle[(i / 2) % pointsStyle.length])
92
- resizeP = resizePoints[i], rotateP = rotatePoints[i], resizeL = resizeLines[Math.floor(i / 2)]
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
- // visible
97
- resizeP.visible = resizeL.visible = resizeable || rotateable
98
- rotateP.visible = rotateable && resizeable
106
+ }
107
+
108
+ public update(bounds: IBoundsData): void {
109
+ this.visible = !this.editor.element.locked
99
110
 
100
- if (i % 2) { // top, right, bottom, left
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
- resizeP.visible = rotateP.visible = !!middlePoint
117
+ const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10
118
+ const showPoints = !(hideOnSmall && width < smallSize && height < smallSize)
103
119
 
104
- if (((i + 1) / 2) % 2) { // top, bottom
105
- resizeL.width = width
106
- if (resizeP.width > width - 30) resizeP.visible = false
107
- } else {
108
- resizeL.height = height
109
- resizeP.rotation = 90
110
- if (resizeP.width > height - 30) resizeP.visible = false
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
- } else {
113
- resizeP.rotation = (i / 2) * 90
149
+
114
150
  }
115
151
 
116
- }
152
+ // rotate
153
+ circle.visible = showPoints && rotateable && !!mergeConfig.rotatePoint
117
154
 
118
- // rotate
119
- circle.visible = rotateable && !!config.rotatePoint
120
- circle.set(this.getPointStyle(config.rotatePoint || pointsStyle[0]))
155
+ // rect
156
+ if (rect.path) rect.path = null // line可能会变成path优先模式
157
+ rect.set({ ...bounds, visible: true })
121
158
 
122
- // rect
123
- rect.set({ stroke, strokeWidth, ...(config.rect || {}) })
124
- rect.set({ ...bounds, visible: true })
125
-
126
- // buttons
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.config
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 getPointStyle(userStyle?: IRectInputData): IRectInputData {
165
- const { stroke, strokeWidth, pointFill, pointSize, pointRadius } = this.editor.config
166
- const defaultStyle = { fill: pointFill, stroke, strokeWidth, width: pointSize, height: pointSize, cornerRadius: pointRadius }
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(): IRectInputData[] {
171
- const { point } = this.editor.config
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(): IRectInputData[] {
176
- const { middlePoint } = this.editor.config
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.target.name === 'rect') this.editor.opacity = this.editor.config.hideOnMove ? 0 : 1 // move
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
- if (e.target.name === 'rect') this.editor.opacity = 1 // move
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.config.resizeable) {
196
- if (editor.config.rotateable) editor.onRotate(e)
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.hasTarget) {
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
- if (move.x || move.y) this.editor.move(move.x, move.y)
275
+ this.editor.move(move)
220
276
  }
221
277
  }
222
278
 
223
- protected onDoubleClick(): void {
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 && editor.element.isBranch) {
226
- //list[0].hitChildren = true
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
- public listenPointEvents(point: IEditPoint, type: IEditPointType, direction: IDirection8): void {
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, () => { this.visible = editor.hasTarget }),
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.DOUBLE_CLICK, this.onDoubleClick, this)
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
+ }
@@ -1,9 +1,9 @@
1
- import { Box } from '@leafer-ui/core'
1
+ import { Box, Direction9 } from '@leafer-ui/draw'
2
2
 
3
- import { IDirection8, IEditPoint, IEditPointType } from '@leafer-in/interface'
3
+ import { IEditPoint, IEditPointType } from '@leafer-in/interface'
4
4
 
5
5
 
6
6
  export class EditPoint extends Box implements IEditPoint {
7
- public direction: IDirection8
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, PointerEvent, DragEvent, MoveEvent, LeafList, Group, ZoomEvent } from '@leafer-ui/core'
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 && this.editor.config.selector }
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 lastDownLeaf: IUI
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.config
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.running) this.targetStroker.forceUpdate()
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
- if (this.running && !this.isMoveMode) {
70
- const find = e.shiftKey ? this.findDeepOne(e) : findOne(e.path)
71
- this.editor.hoverTarget = this.editor.hasItem(find) ? null : find
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
- this.editor.hoverTarget = null // move.dragEmpty
75
+ editor.hoverTarget = null // move.dragEmpty
74
76
  }
75
77
  }
76
78
 
77
79
  protected onBeforeDown(e: PointerEvent): void {
78
- if (this.running && !this.isMoveMode && !e.middle) {
79
- const find = this.lastDownLeaf = findOne(e.path)
80
+ const { select } = this.editor.mergeConfig
81
+ if (select === 'press') this.checkAndSelect(e)
82
+ }
80
83
 
81
- if (find) {
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
- if (e.shiftKey) {
84
- this.editor.shiftItem(find)
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
- this.editor.target = find
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) this.editor.target = null
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.running && this.allowDrag(e)) {
123
+ if (this.allowDrag(e)) {
116
124
  const { editor } = this
117
- const { stroke, strokeWidth, area } = editor.config
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, strokeWidth, x, y }, area)
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.config.boxSelect && !e.target.draggable) {
187
- return (!this.editor.hasTarget && this.allow(e.target)) || (e.shiftKey && !findOne(e.path))
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 findDeepOne(e: PointerEvent): IUI {
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.lastDownLeaf = null
251
+ this.editor = this.originList = this.needRemoveItem = null
233
252
  this.__removeListenEvents()
234
253
  super.destroy()
235
254
  }
@@ -1,5 +1,5 @@
1
1
  import { IBoundsData, IGroupInputData, IRect, IRectInputData } from '@leafer-ui/interface'
2
- import { Group, Rect } from '@leafer-ui/core'
2
+ import { Group, Rect } from '@leafer-ui/draw'
3
3
 
4
4
  import { ISelectArea } from '@leafer-in/interface'
5
5