@leafer-in/editor 1.0.0-rc.21 → 1.0.0-rc.22

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,8 +1,8 @@
1
- import { IRect, IAround, IEventListenerId, IBoundsData, IRectInputData, IPointData, IKeyEvent, IGroup, IBox } from '@leafer-ui/interface'
2
- import { Group, Box, AroundHelper } from '@leafer-ui/draw'
1
+ import { IRect, IAround, IEventListenerId, IBoundsData, IPointData, IKeyEvent, IGroup, IBox, IBoxInputData } from '@leafer-ui/interface'
2
+ import { Group, Box, AroundHelper, Direction9 } from '@leafer-ui/draw'
3
3
  import { DragEvent, PointerEvent } from '@leafer-ui/core'
4
4
 
5
- import { IEditBox, IEditor, IDirection8, IEditPoint, IEditPointType } from '@leafer-in/interface'
5
+ import { IEditBox, IEditor, IEditPoint, IEditPointType } from '@leafer-in/interface'
6
6
 
7
7
  import { updateCursor, updateMoveCursor } from '../editor/cursor'
8
8
  import { EditorEvent } from '../event/EditorEvent'
@@ -18,6 +18,8 @@ export class EditBox extends Group implements IEditBox {
18
18
  public dragging: boolean
19
19
  public moving: boolean
20
20
 
21
+ public view: IGroup = new Group() // 放置默认编辑工具控制点
22
+
21
23
  public rect: IBox = new Box({ name: 'rect', hitFill: 'all', hitStroke: 'none', strokeAlign: 'center', hitRadius: 5 }) // target rect
22
24
  public circle: IEditPoint = new EditPoint({ name: 'circle', strokeAlign: 'center', around: 'center', cursor: 'crosshair', hitRadius: 5 }) // rotate point
23
25
 
@@ -47,7 +49,7 @@ export class EditBox extends Group implements IEditBox {
47
49
 
48
50
  public create() {
49
51
  let rotatePoint: IEditPoint, resizeLine: IEditPoint, resizePoint: IEditPoint
50
- const { resizePoints, rotatePoints, resizeLines, rect, circle, buttons } = this
52
+ const { view, resizePoints, rotatePoints, resizeLines, rect, circle, buttons } = this
51
53
  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 }]
52
54
 
53
55
  for (let i = 0; i < 8; i++) {
@@ -61,7 +63,7 @@ export class EditBox extends Group implements IEditBox {
61
63
  this.listenPointEvents(resizeLine, 'resize', i)
62
64
  }
63
65
 
64
- resizePoint = new EditPoint({ name: 'resize-point', around: 'center', strokeAlign: 'center', hitRadius: 5 })
66
+ resizePoint = new EditPoint({ name: 'resize-point', hitRadius: 5 })
65
67
  resizePoints.push(resizePoint)
66
68
  this.listenPointEvents(resizePoint, 'resize', i)
67
69
  }
@@ -69,73 +71,98 @@ export class EditBox extends Group implements IEditBox {
69
71
  buttons.add(circle)
70
72
  this.listenPointEvents(circle, 'rotate', 2)
71
73
 
72
- this.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints)
74
+ view.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints)
75
+ this.add(view)
73
76
  }
74
77
 
75
- // update
76
-
77
- public update(bounds: IBoundsData): void {
78
- const { config, list } = this.editor
79
- const { width, height } = bounds
80
- const { rect, circle, resizePoints, rotatePoints, resizeLines } = this
81
- const { middlePoint, resizeable, rotateable, stroke, strokeWidth, hideOnSmall } = config
78
+ public load(): void {
79
+ const { mergeConfig, element, single } = this.editor
80
+ const { rect, circle, resizePoints } = this
81
+ const { stroke, strokeWidth, moveable } = mergeConfig
82
82
 
83
83
  const pointsStyle = this.getPointsStyle()
84
84
  const middlePointsStyle = this.getMiddlePointsStyle()
85
- const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10
86
- const showPoints = !(hideOnSmall && width < smallSize && height < smallSize)
87
-
88
- this.visible = list[0] && !list[0].locked // check locked
89
85
 
90
- let point = {} as IPointData, style: IRectInputData, rotateP: IRect, resizeP: IRect, resizeL: IRect
86
+ let resizeP: IRect
91
87
 
92
88
  for (let i = 0; i < 8; i++) {
89
+ resizeP = resizePoints[i]
90
+ resizeP.set(this.getPointStyle((i % 2) ? middlePointsStyle[((i - 1) / 2) % middlePointsStyle.length] : pointsStyle[(i / 2) % pointsStyle.length]))
91
+ if (!(i % 2)) resizeP.rotation = (i / 2) * 90
92
+ }
93
93
 
94
- AroundHelper.toPoint(AroundHelper.directionData[i], bounds, point)
95
- style = this.getPointStyle((i % 2) ? middlePointsStyle[((i - 1) / 2) % middlePointsStyle.length] : pointsStyle[(i / 2) % pointsStyle.length])
96
- resizeP = resizePoints[i], rotateP = rotatePoints[i], resizeL = resizeLines[Math.floor(i / 2)]
97
- resizeP.set(style)
98
- resizeP.set(point), rotateP.set(point), resizeL.set(point)
94
+ // rotate
95
+ circle.set(this.getPointStyle(mergeConfig.rotatePoint || pointsStyle[0]))
99
96
 
100
- // visible
101
- resizeP.visible = resizeL.visible = showPoints && (resizeable || rotateable)
102
- rotateP.visible = showPoints && rotateable && resizeable && !config.rotatePoint
97
+ // rect
98
+ rect.set({ stroke, strokeWidth, ...(mergeConfig.rect || {}) })
99
+ rect.hittable = !single && moveable
103
100
 
104
- if (i % 2) { // top, right, bottom, left
101
+ // 编辑框作为底部虚拟元素, onSelect 方法移除
102
+ element.syncEventer = (single && moveable) ? rect : null
103
+ this.app.interaction.bottomList = (single && moveable) ? [{ target: rect, proxy: element }] : null
105
104
 
106
- resizeP.visible = rotateP.visible = showPoints && !!middlePoint
105
+ this.visible = !element.locked
106
+ }
107
107
 
108
- if (((i + 1) / 2) % 2) { // top, bottom
109
- resizeL.width = width
110
- if (resizeP.width > width - 30) resizeP.visible = false
111
- } else {
112
- resizeL.height = height
113
- resizeP.rotation = 90
114
- if (resizeP.width > height - 30) resizeP.visible = false
108
+ public update(bounds: IBoundsData): void {
109
+ if (this.view.worldOpacity) {
110
+ const { mergeConfig } = this.editor
111
+ const { width, height } = bounds
112
+ const { rect, circle, resizePoints, rotatePoints, resizeLines } = this
113
+ const { middlePoint, resizeable, rotateable, hideOnSmall } = mergeConfig
114
+
115
+ const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10
116
+ const showPoints = !(hideOnSmall && width < smallSize && height < smallSize)
117
+
118
+ let point = {} as IPointData, rotateP: IRect, resizeP: IRect, resizeL: IRect
119
+
120
+ for (let i = 0; i < 8; i++) {
121
+
122
+ AroundHelper.toPoint(AroundHelper.directionData[i], bounds, point)
123
+ resizeP = resizePoints[i]
124
+ rotateP = rotatePoints[i]
125
+ resizeL = resizeLines[Math.floor(i / 2)]
126
+ resizeP.set(point)
127
+ rotateP.set(point)
128
+ resizeL.set(point)
129
+
130
+ // visible
131
+ resizeP.visible = resizeL.visible = showPoints && (resizeable || rotateable)
132
+ rotateP.visible = showPoints && rotateable && resizeable && !mergeConfig.rotatePoint
133
+
134
+ if (i % 2) { // top, right, bottom, left
135
+
136
+ resizeP.visible = rotateP.visible = showPoints && !!middlePoint
137
+
138
+ if (((i + 1) / 2) % 2) { // top, bottom
139
+ resizeL.width = width
140
+ if (resizeP.width > width - 30) resizeP.visible = false
141
+ } else {
142
+ resizeL.height = height
143
+ resizeP.rotation = 90
144
+ if (resizeP.width > height - 30) resizeP.visible = false
145
+ }
115
146
  }
116
- } else {
117
- resizeP.rotation = (i / 2) * 90
118
- }
119
147
 
120
- }
148
+ }
121
149
 
122
- // rotate
123
- circle.visible = showPoints && rotateable && !!config.rotatePoint
124
- circle.set(this.getPointStyle(config.rotatePoint || pointsStyle[0]))
150
+ // rotate
151
+ circle.visible = showPoints && rotateable && !!mergeConfig.rotatePoint
125
152
 
126
- // rect
127
- rect.set({ stroke, strokeWidth, ...(config.rect || {}) })
128
- rect.set({ ...bounds, visible: true })
129
- rect.hittable = config.moveable
153
+ // rect
154
+ rect.set({ ...bounds, visible: true })
130
155
 
131
- // buttons
132
- this.buttons.visible = showPoints
133
- this.layoutButtons()
156
+ // buttons
157
+ const buttonVisible = showPoints && (circle.visible || this.buttons.children.length > 1)
158
+ this.buttons.visible = buttonVisible
159
+ if (buttonVisible) this.layoutButtons()
160
+ }
134
161
  }
135
162
 
136
163
  protected layoutButtons(): void {
137
164
  const { buttons, resizePoints } = this
138
- const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.editor.config
165
+ const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.editor.mergeConfig
139
166
 
140
167
  const { flippedX, flippedY } = this
141
168
  let index = fourDirection.indexOf(buttonsDirection)
@@ -167,44 +194,55 @@ export class EditBox extends Group implements IEditBox {
167
194
 
168
195
  }
169
196
 
170
- public getPointStyle(userStyle?: IRectInputData): IRectInputData {
171
- const { stroke, strokeWidth, pointFill, pointSize, pointRadius } = this.editor.config
172
- const defaultStyle = { fill: pointFill, stroke, strokeWidth, width: pointSize, height: pointSize, cornerRadius: pointRadius }
197
+ public unload(): void {
198
+ this.visible = false
199
+ }
200
+
201
+
202
+ public getPointStyle(userStyle?: IBoxInputData): IBoxInputData {
203
+ const { stroke, strokeWidth, pointFill, pointSize, pointRadius } = this.editor.mergeConfig
204
+ const defaultStyle = { fill: pointFill, stroke, strokeWidth, around: 'center', strokeAlign: 'center', width: pointSize, height: pointSize, cornerRadius: pointRadius } as IBoxInputData
173
205
  return userStyle ? Object.assign(defaultStyle, userStyle) : defaultStyle
174
206
  }
175
207
 
176
- public getPointsStyle(): IRectInputData[] {
177
- const { point } = this.editor.config
208
+ public getPointsStyle(): IBoxInputData[] {
209
+ const { point } = this.editor.mergeConfig
178
210
  return point instanceof Array ? point : [point]
179
211
  }
180
212
 
181
- public getMiddlePointsStyle(): IRectInputData[] {
182
- const { middlePoint } = this.editor.config
213
+ public getMiddlePointsStyle(): IBoxInputData[] {
214
+ const { middlePoint } = this.editor.mergeConfig
183
215
  return middlePoint instanceof Array ? middlePoint : (middlePoint ? [middlePoint] : this.getPointsStyle())
184
216
  }
185
217
 
218
+ protected onSelect(e: EditorEvent): void {
219
+ if (e.oldList.length === 1) e.oldList[0].syncEventer = this.app.interaction.bottomList = null
220
+ }
221
+
186
222
  // drag
187
223
 
188
224
  protected onDragStart(e: DragEvent): void {
189
225
  this.dragging = true
190
- if (e.target.name === 'rect') {
226
+ if (e.current.name === 'rect') {
227
+ const { editor } = this
191
228
  this.moving = true
192
- this.editor.opacity = this.editor.config.hideOnMove ? 0 : 1 // move
229
+ editor.dragStartPoint = { x: editor.element.x, y: editor.element.y }
230
+ editor.opacity = editor.mergeConfig.hideOnMove ? 0 : 1 // move
193
231
  }
194
232
  }
195
233
 
196
234
  protected onDragEnd(e: DragEvent): void {
197
235
  this.dragging = false
198
236
  this.moving = false
199
- if (e.target.name === 'rect') this.editor.opacity = 1 // move
237
+ if (e.current.name === 'rect') this.editor.opacity = 1 // move
200
238
 
201
239
  }
202
240
 
203
241
  protected onDrag(e: DragEvent): void {
204
242
  const { editor } = this
205
243
  const point = this.enterPoint = e.current as IEditPoint
206
- if (point.pointType === 'rotate' || e.metaKey || e.ctrlKey || !editor.config.resizeable) {
207
- if (editor.config.rotateable) editor.onRotate(e)
244
+ if (point.pointType === 'rotate' || e.metaKey || e.ctrlKey || !editor.mergeConfig.resizeable) {
245
+ if (editor.mergeConfig.rotateable) editor.onRotate(e)
208
246
  } else {
209
247
  editor.onScale(e)
210
248
  }
@@ -212,7 +250,7 @@ export class EditBox extends Group implements IEditBox {
212
250
  }
213
251
 
214
252
  public onArrow(e: IKeyEvent): void {
215
- if (this.editor.hasTarget && this.editor.config.keyEvent) {
253
+ if (this.editor.editing && this.editor.mergeConfig.keyEvent) {
216
254
  const move = { x: 0, y: 0 }
217
255
  const distance = e.shiftKey ? 10 : 1
218
256
  switch (e.code) {
@@ -228,18 +266,34 @@ export class EditBox extends Group implements IEditBox {
228
266
  case 'ArrowRight':
229
267
  move.x = distance
230
268
  }
231
- if (move.x || move.y) this.editor.move(move.x, move.y)
269
+ this.editor.move(move)
232
270
  }
233
271
  }
234
272
 
235
- protected onDoubleClick(): void {
273
+
274
+ protected onDoubleTap(e: PointerEvent): void {
275
+ if (this.editor.mergeConfig.openInner === 'double') this.openInner(e)
276
+ }
277
+
278
+ protected onLongPress(e: PointerEvent): void {
279
+ if (this.editor.mergeConfig.openInner === 'long') this.openInner(e)
280
+ }
281
+
282
+ protected openInner(e: PointerEvent): void {
236
283
  const { editor } = this
237
- if (editor.single && editor.element.isBranch) {
238
- //list[0].hitChildren = true
284
+ if (editor.single) {
285
+ const { element } = editor
286
+ if (element.isBranch) {
287
+ editor.openGroup(element as IGroup)
288
+ editor.target = editor.selector.findDeepOne(e)
289
+ } else {
290
+ editor.openInnerEditor()
291
+ }
239
292
  }
240
293
  }
241
294
 
242
- public listenPointEvents(point: IEditPoint, type: IEditPointType, direction: IDirection8): void {
295
+
296
+ public listenPointEvents(point: IEditPoint, type: IEditPointType, direction: Direction9): void {
243
297
  const { editor } = this
244
298
  point.direction = direction
245
299
  point.pointType = type
@@ -253,12 +307,13 @@ export class EditBox extends Group implements IEditBox {
253
307
  protected __listenEvents(): void {
254
308
  const { rect, editor } = this
255
309
  this.__eventIds = [
256
- editor.on_(EditorEvent.SELECT, () => { this.visible = editor.hasTarget }),
310
+ editor.on_(EditorEvent.SELECT, this.onSelect, this),
257
311
  rect.on_(DragEvent.START, this.onDragStart, this),
258
312
  rect.on_(DragEvent.DRAG, editor.onMove, editor),
259
313
  rect.on_(DragEvent.END, this.onDragEnd, this),
260
314
  rect.on_(PointerEvent.ENTER, () => updateMoveCursor(editor)),
261
- rect.on_(PointerEvent.DOUBLE_CLICK, this.onDoubleClick, this)
315
+ rect.on_(PointerEvent.DOUBLE_TAP, this.onDoubleTap, this),
316
+ rect.on_(PointerEvent.LONG_PRESS, this.onLongPress, this)
262
317
  ]
263
318
  }
264
319
 
@@ -1,9 +1,9 @@
1
- import { Box } from '@leafer-ui/draw'
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,4 +1,4 @@
1
- import { IBounds, ILeaf, ILeafList, IUI, IEventListenerId } from '@leafer-ui/interface'
1
+ import { IBounds, ILeaf, ILeafList, IUI, IEventListenerId, IPointerEvent } from '@leafer-ui/interface'
2
2
  import { Bounds, LeafList, Group } from '@leafer-ui/draw'
3
3
  import { PointerEvent, DragEvent, MoveEvent, ZoomEvent } from '@leafer-ui/core'
4
4
 
@@ -17,7 +17,7 @@ export class EditSelect extends Group implements IEditSelect {
17
17
  public editor: IEditor
18
18
 
19
19
  public get dragging(): boolean { return !!this.originList }
20
- 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 }
21
21
  public get isMoveMode(): boolean { return this.app && this.app.interaction.moveMode }
22
22
 
23
23
  public hoverStroker: IStroker = new Stroker()
@@ -27,7 +27,7 @@ export class EditSelect extends Group implements IEditSelect {
27
27
  public selectArea: ISelectArea = new SelectArea()
28
28
 
29
29
  protected originList: ILeafList
30
- protected lastDownLeaf: IUI
30
+ protected needRemoveItem: IUI
31
31
 
32
32
  protected __eventIds: IEventListenerId[] = []
33
33
 
@@ -44,8 +44,8 @@ export class EditSelect extends Group implements IEditSelect {
44
44
  protected onHover(): void {
45
45
  const { editor } = this
46
46
  if (this.running && !this.dragging && !editor.dragging) {
47
- const { stroke, strokeWidth, hover } = editor.config
48
- 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 || {}) })
49
49
  } else {
50
50
  this.hoverStroker.target = null
51
51
  }
@@ -53,7 +53,7 @@ export class EditSelect extends Group implements IEditSelect {
53
53
 
54
54
  protected onSelect(): void {
55
55
  if (this.running) {
56
- const { config, list } = this.editor
56
+ const { mergeConfig: config, list } = this.editor
57
57
  const { stroke, strokeWidth } = config
58
58
  this.targetStroker.setTarget(list, { stroke, strokeWidth: Math.max(1, strokeWidth / 2) })
59
59
  this.hoverStroker.target = null
@@ -61,7 +61,7 @@ export class EditSelect extends Group implements IEditSelect {
61
61
  }
62
62
 
63
63
  public update(): void {
64
- if (this.running) this.targetStroker.forceUpdate()
64
+ if (this.targetStroker.target) this.targetStroker.forceUpdate()
65
65
  }
66
66
 
67
67
  // move / down
@@ -69,7 +69,7 @@ export class EditSelect extends Group implements IEditSelect {
69
69
  protected onPointerMove(e: PointerEvent): void {
70
70
  const { app, editor } = this
71
71
  if (this.running && !this.isMoveMode && app.config.pointer.hover && !app.interaction.dragging) {
72
- const find = e.shiftKey ? this.findDeepOne(e) : findOne(e.path)
72
+ const find = this.findUI(e)
73
73
  editor.hoverTarget = editor.hasItem(find) ? null : find
74
74
  } if (this.isMoveMode) {
75
75
  editor.hoverTarget = null // move.dragEmpty
@@ -77,45 +77,38 @@ export class EditSelect extends Group implements IEditSelect {
77
77
  }
78
78
 
79
79
  protected onBeforeDown(e: PointerEvent): void {
80
- const { select } = this.editor.config
81
- if (select === 'press') this.checkAndSelect(e, true)
80
+ const { select } = this.editor.mergeConfig
81
+ if (select === 'press') this.checkAndSelect(e)
82
82
  }
83
83
 
84
84
  protected onTap(e: PointerEvent): void {
85
85
  const { editor } = this
86
- const { select, continuousSelect } = editor.config
86
+ const { select } = editor.mergeConfig
87
87
  if (select === 'tap') this.checkAndSelect(e)
88
88
 
89
- if (this.running && (e.shiftKey || continuousSelect) && !e.middle && !this.lastDownLeaf) {
90
- const find = this.findDeepOne(e)
91
- if (find) editor.shiftItem(find)
92
- else if (!e.shiftKey && continuousSelect) editor.target = null
89
+ if (this.needRemoveItem) {
90
+ editor.removeItem(this.needRemoveItem)
93
91
  } else if (this.isMoveMode) {
94
92
  editor.target = null // move.dragEmpty
95
93
  }
96
94
 
97
- this.lastDownLeaf = null
98
95
  }
99
96
 
100
- protected checkAndSelect(e: PointerEvent, isDownType?: boolean): void { // pointer.down or tap
101
- if (this.running && !this.isMoveMode && !e.middle) {
97
+ protected checkAndSelect(e: PointerEvent): void { // pointer.down or tap
98
+ this.needRemoveItem = null
99
+
100
+ if (this.allowSelect(e)) {
102
101
  const { editor } = this
103
- const find = this.lastDownLeaf = findOne(e.path)
102
+ const find = this.findUI(e)
104
103
 
105
104
  if (find) {
106
-
107
- if (e.shiftKey || editor.config.continuousSelect) {
108
- editor.shiftItem(find)
105
+ if (this.isMultipleSelect(e)) {
106
+ if (editor.hasItem(find)) this.needRemoveItem = find // 等待tap事件再实际移除
107
+ else editor.addItem(find)
109
108
  } else {
110
109
  editor.target = find
111
110
  }
112
111
 
113
- // change down data
114
- if (isDownType) {
115
- editor.updateLayout()
116
- if (!find.locked) this.app.interaction.updateDownData(e, { findList: [editor.editBox.rect] }, editor.config.dualEvent)
117
- }
118
-
119
112
  } else if (this.allow(e.target)) {
120
113
 
121
114
  if (!e.shiftKey) editor.target = null
@@ -127,14 +120,14 @@ export class EditSelect extends Group implements IEditSelect {
127
120
  // drag
128
121
 
129
122
  protected onDragStart(e: DragEvent): void {
130
- if (this.running && this.allowDrag(e)) {
123
+ if (this.allowDrag(e)) {
131
124
  const { editor } = this
132
- const { stroke, strokeWidth, area } = editor.config
125
+ const { stroke, area } = editor.mergeConfig
133
126
  const { x, y } = e.getInner(this)
134
127
 
135
128
  this.bounds.set(x, y)
136
129
 
137
- this.selectArea.setStyle({ visible: true, stroke, strokeWidth, x, y }, area)
130
+ this.selectArea.setStyle({ visible: true, stroke, x, y }, area)
138
131
  this.selectArea.setBounds(this.bounds.get())
139
132
 
140
133
  this.originList = editor.leafList.clone()
@@ -197,18 +190,30 @@ export class EditSelect extends Group implements IEditSelect {
197
190
  }
198
191
 
199
192
  protected allowDrag(e: DragEvent) {
200
- if (this.editor.config.boxSelect && !e.target.draggable) {
201
- 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))
202
195
  } else {
203
196
  return false
204
197
  }
205
198
  }
206
199
 
207
- 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 {
208
205
  const options = { exclude: new LeafList(this.editor.editBox.rect) }
209
206
  return findOne(e.target.leafer.interaction.findPath(e, options)) as IUI
210
207
  }
211
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
+
212
217
  protected __listenEvents(): void {
213
218
  const { editor } = this
214
219
  editor.waitLeafer(() => {
@@ -243,7 +248,7 @@ export class EditSelect extends Group implements IEditSelect {
243
248
  }
244
249
 
245
250
  public destroy(): void {
246
- this.editor = this.originList = this.lastDownLeaf = null
251
+ this.editor = this.originList = this.needRemoveItem = null
247
252
  this.__removeListenEvents()
248
253
  super.destroy()
249
254
  }
@@ -24,8 +24,7 @@ export class Stroker extends UI implements IStroker {
24
24
  }
25
25
 
26
26
  public setTarget(target: IUI | IUI[], style: IRectInputData): void {
27
- const { stroke, strokeWidth } = style
28
- this.set({ stroke, strokeWidth })
27
+ this.set(style)
29
28
  this.target = target
30
29
  }
31
30
 
@@ -34,7 +33,7 @@ export class Stroker extends UI implements IStroker {
34
33
  if (list.length) {
35
34
 
36
35
  let leaf: IUI
37
- const { stroke, strokeWidth } = this.__
36
+ const { stroke, strokeWidth, fill } = this.__
38
37
  const { bounds } = options
39
38
 
40
39
  for (let i = 0; i < list.length; i++) {
@@ -73,7 +72,8 @@ export class Stroker extends UI implements IStroker {
73
72
  this.__.strokeWidth = strokeWidth / abs(leaf.__world.scaleX)
74
73
  }
75
74
 
76
- typeof stroke === 'string' ? Paint.stroke(stroke, this, canvas) : Paint.strokes(stroke, this, canvas)
75
+ if (stroke) typeof stroke === 'string' ? Paint.stroke(stroke, this, canvas) : Paint.strokes(stroke, this, canvas)
76
+ if (fill) typeof fill === 'string' ? Paint.fill(fill, this, canvas) : Paint.fills(fill, this, canvas)
77
77
  }
78
78
  }
79
79
 
@@ -10,11 +10,11 @@ const cacheCursors: IObject = {}
10
10
 
11
11
  export function updateCursor(editor: IEditor, e: IUIEvent): void {
12
12
  const { editBox } = editor, point = editBox.enterPoint
13
- if (!point || !editor.hasTarget || !editBox.visible) return
13
+ if (!point || !editor.editing || !editBox.visible) return
14
14
  if (point.name === 'circle') return // 独立旋转按钮
15
15
 
16
16
  let { rotation } = editBox
17
- const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.config
17
+ const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig
18
18
  const { pointType } = point, { flippedX, flippedY } = editBox
19
19
 
20
20
  let showResize = pointType === 'resize'
@@ -36,7 +36,7 @@ export function updateCursor(editor: IEditor, e: IUIEvent): void {
36
36
  }
37
37
 
38
38
  export function updateMoveCursor(editor: IEditor): void {
39
- editor.editBox.rect.cursor = editor.config.moveCursor
39
+ editor.editBox.rect.cursor = editor.mergeConfig.moveCursor
40
40
  }
41
41
 
42
42
 
@@ -16,8 +16,9 @@ export function onTarget(editor: IEditor, oldValue: IUI | IUI[]): void {
16
16
  }
17
17
 
18
18
  editor.emitEvent(new EditorEvent(EditorEvent.SELECT, { editor, value: target, oldValue }))
19
+ editor.checkOpenedGroups()
19
20
 
20
- if (editor.hasTarget) {
21
+ if (editor.editing) {
21
22
  editor.waitLeafer(() => {
22
23
  if (editor.multiple) simulate(editor)
23
24
  updateMoveCursor(editor)
@@ -26,6 +27,7 @@ export function onTarget(editor: IEditor, oldValue: IUI | IUI[]): void {
26
27
  editor.listenTargetEvents()
27
28
  })
28
29
  } else {
30
+ editor.updateEditTool()
29
31
  editor.removeTargetEvents()
30
32
  }
31
33
  }
@@ -1,6 +1,7 @@
1
1
  import { IAround, IDragEvent, IMatrixData } from '@leafer-ui/interface'
2
2
 
3
- import { IDirection8, IEditorScaleEvent } from '@leafer-in/interface'
3
+ import { IEditorScaleEvent } from '@leafer-in/interface'
4
+ import { Direction9 } from '@leafer-ui/draw'
4
5
 
5
6
  import { EditorEvent } from './EditorEvent'
6
7
 
@@ -16,7 +17,7 @@ export class EditorScaleEvent extends EditorEvent implements IEditorScaleEvent {
16
17
 
17
18
  readonly drag: IDragEvent
18
19
 
19
- readonly direction: IDirection8
20
+ readonly direction: Direction9
20
21
  readonly lockRatio: boolean
21
22
  readonly around: IAround
22
23
 
@@ -1,15 +1,15 @@
1
1
  import { IBoundsData, IPointData, IAround } from '@leafer-ui/interface'
2
- import { AroundHelper, PointHelper } from '@leafer-ui/draw'
2
+ import { AroundHelper, PointHelper, Direction9 } from '@leafer-ui/draw'
3
3
 
4
- import { IEditorScaleEvent, IDirection8, IEditorSkewEvent, IEditorRotateEvent } from '@leafer-in/interface'
4
+ import { IEditorScaleEvent, IEditorSkewEvent, IEditorRotateEvent } from '@leafer-in/interface'
5
5
 
6
6
 
7
- const { topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left } = IDirection8
7
+ const { topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left } = Direction9
8
8
  const { toPoint } = AroundHelper
9
9
 
10
10
  export const EditDataHelper = {
11
11
 
12
- getScaleData(bounds: IBoundsData, direction: IDirection8, pointMove: IPointData, lockRatio: boolean | 'corner', around: IAround): IEditorScaleEvent {
12
+ getScaleData(bounds: IBoundsData, direction: Direction9, pointMove: IPointData, lockRatio: boolean | 'corner', around: IAround): IEditorScaleEvent {
13
13
  let origin: IPointData, scaleX: number = 1, scaleY: number = 1
14
14
  const { width, height } = bounds
15
15
 
@@ -67,10 +67,7 @@ export const EditDataHelper = {
67
67
 
68
68
  if (lockRatio) {
69
69
  const unlockSide = lockRatio === 'corner' && direction % 2
70
- if (!unlockSide) {
71
- if (scaleY !== 1) scaleX = scaleY
72
- else scaleY = scaleX
73
- }
70
+ if (!unlockSide) scaleX = scaleY = Math.sqrt(scaleX * scaleY)
74
71
  }
75
72
 
76
73
  toPoint(around || origin, bounds, origin)
@@ -78,7 +75,7 @@ export const EditDataHelper = {
78
75
  return { origin, scaleX, scaleY, direction, lockRatio, around }
79
76
  },
80
77
 
81
- getRotateData(bounds: IBoundsData, direction: IDirection8, current: IPointData, last: IPointData, around: IAround): IEditorRotateEvent {
78
+ getRotateData(bounds: IBoundsData, direction: Direction9, current: IPointData, last: IPointData, around: IAround): IEditorRotateEvent {
82
79
  let origin: IPointData
83
80
 
84
81
  switch (direction) {
@@ -103,7 +100,7 @@ export const EditDataHelper = {
103
100
  return { origin, rotation: PointHelper.getRotation(last, origin, current) }
104
101
  },
105
102
 
106
- getSkewData(bounds: IBoundsData, direction: IDirection8, move: IPointData, around: IAround): IEditorSkewEvent {
103
+ getSkewData(bounds: IBoundsData, direction: Direction9, move: IPointData, around: IAround): IEditorSkewEvent {
107
104
  let origin: IPointData, skewX = 0, skewY = 0
108
105
  let last: IPointData
109
106
 
@@ -153,7 +150,7 @@ export const EditDataHelper = {
153
150
  return direction
154
151
  },
155
152
 
156
- getFlipDirection(direction: IDirection8, flipedX: boolean, flipedY: boolean): IDirection8 {
153
+ getFlipDirection(direction: Direction9, flipedX: boolean, flipedY: boolean): Direction9 {
157
154
  if (flipedX) {
158
155
  switch (direction) {
159
156
  case left: direction = right; break