@leafer-in/editor 1.9.6 → 1.9.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leafer-in/editor",
3
- "version": "1.9.6",
3
+ "version": "1.9.8",
4
4
  "description": "@leafer-in/editor",
5
5
  "author": "Chao (Leafer) Wan",
6
6
  "license": "MIT",
@@ -34,10 +34,10 @@
34
34
  "leaferjs"
35
35
  ],
36
36
  "peerDependencies": {
37
- "@leafer-ui/draw": "^1.9.6",
38
- "@leafer-ui/core": "^1.9.6",
39
- "@leafer-in/resize": "^1.9.6",
40
- "@leafer-ui/interface": "^1.9.6",
41
- "@leafer-in/interface": "^1.9.6"
37
+ "@leafer-ui/draw": "^1.9.8",
38
+ "@leafer-ui/core": "^1.9.8",
39
+ "@leafer-in/resize": "^1.9.8",
40
+ "@leafer-ui/interface": "^1.9.8",
41
+ "@leafer-in/interface": "^1.9.8"
42
42
  }
43
43
  }
package/src/Editor.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IGroupInputData, IUI, IEventListenerId, IPointData, ILeafList, IEditSize, IGroup, IObject, IAlign, IAxis, IFunction, IMatrix, IApp, ILeaferMode } from '@leafer-ui/interface'
2
- import { Group, DataHelper, LeafList, RenderEvent, LeafHelper, Direction9, Plugin, isString, PropertyEvent, LeaferEvent } from '@leafer-ui/draw'
2
+ import { Group, DataHelper, LeafList, RenderEvent, LeafHelper, Direction9, Plugin, isString, PropertyEvent, LeaferEvent, isArray } from '@leafer-ui/draw'
3
3
  import { DragEvent, RotateEvent, ZoomEvent, MoveEvent, useModule } from '@leafer-ui/core'
4
4
 
5
5
  import { IEditBox, IEditPoint, IEditor, IEditorConfig, IEditTool, IEditorScaleEvent, IInnerEditor, ISimulateElement } from '@leafer-in/interface'
@@ -29,11 +29,13 @@ export class Editor extends Group implements IEditor {
29
29
  readonly mergeConfig: IEditorConfig
30
30
  readonly mergedConfig: IEditorConfig
31
31
 
32
+ @targetAttr(onTarget)
33
+ public target?: IUI | IUI[]
34
+
32
35
  @targetAttr(onHover)
33
36
  public hoverTarget?: IUI
34
37
 
35
- @targetAttr(onTarget)
36
- public target?: IUI | IUI[]
38
+ public dimTarget?: IGroup | IGroup[] // 需要淡化的容器
37
39
 
38
40
  // 列表
39
41
 
@@ -121,6 +123,20 @@ export class Editor extends Group implements IEditor {
121
123
  this.hasItem(item) ? this.removeItem(item) : this.addItem(item)
122
124
  }
123
125
 
126
+ // 淡化 / 突出
127
+
128
+ public setDimOthers(value: boolean | number, attrName: 'bright' | 'dim' = 'dim', list?: IUI[]): void {
129
+ if (!list) {
130
+ const { dimTarget, targetLeafer } = this
131
+ list = dimTarget ? (isArray(dimTarget) ? dimTarget : [dimTarget]) : [targetLeafer]
132
+ }
133
+ if (list[0] && list[0][attrName] !== (value || false)) list.forEach(item => DataHelper.stintSet(item, attrName, value))
134
+ }
135
+
136
+ public setBright(value: boolean): void {
137
+ this.setDimOthers(value, 'bright', this.list)
138
+ }
139
+
124
140
  // update
125
141
 
126
142
  public update(): void {
@@ -15,23 +15,28 @@ export function targetAttr(fn: IFunction) {
15
15
  const old = (this as IObject)[privateKey]
16
16
  if (old !== value) {
17
17
 
18
- if ((this as IEditor).config) { // Editor
18
+ const t = this as IEditor
19
+
20
+ if (t.config) { // Editor
19
21
 
20
22
  const isSelect = key === 'target'
21
23
  if (isSelect) {
22
- if (isArray(value) && value.length > 1 && value[0].locked) value.splice(0, 1) // fix: 单个锁定 + shift多选
23
- if ((this as IEditor).single) (this as IEditor).element.syncEventer = null // 重置 EditBox.load() 设置
24
-
25
- const { beforeSelect } = (this as IEditor).config
24
+ const { beforeSelect } = t.config
26
25
  if (beforeSelect) {
27
26
  const check = beforeSelect({ target: value })
28
27
  if (isObject(check)) value = check
29
28
  else if (check === false) return
30
29
  }
30
+
31
+ t.setDimOthers(false)
32
+ t.setBright(false)
33
+
34
+ if (isArray(value) && value.length > 1 && value[0].locked) value.splice(0, 1) // fix: 单个锁定 + shift多选
35
+ if (t.single) t.element.syncEventer = null // 重置 EditBox.load() 设置
31
36
  }
32
37
 
33
38
  const type = isSelect ? EditorEvent.BEFORE_SELECT : EditorEvent.BEFORE_HOVER
34
- if (this.hasEvent(type)) this.emitEvent(new EditorEvent(type, { editor: this as IEditor, value: value as IUI, oldValue: old }))
39
+ if (this.hasEvent(type)) this.emitEvent(new EditorEvent(type, { editor: t, value: value as IUI, oldValue: old }))
35
40
  }
36
41
 
37
42
  (this as IObject)[privateKey] = value, fn(this, old)
@@ -1,5 +1,5 @@
1
- import { IRect, IEventListenerId, IBoundsData, IPointData, IKeyEvent, IGroup, IBox, IBoxInputData, IAlign, IUI, IEditorConfig, IEditorDragStartData, IEventParams, ITransformTool, IUIEvent } from '@leafer-ui/interface'
2
- import { Group, Box, Text, AroundHelper, Direction9, ResizeEvent, BoundsHelper, isArray, isString, isNumber } from '@leafer-ui/draw'
1
+ import { IRect, IEventListenerId, IBoundsData, IPointData, IKeyEvent, IGroup, IBox, IBoxInputData, IAlign, IUI, IEditorConfig, IEditorDragStartData, ITransformTool, IUIEvent, IEditPointInputData } from '@leafer-ui/interface'
2
+ import { Group, Text, AroundHelper, Direction9, ResizeEvent, BoundsHelper, isArray, isString, isNumber, getPointData } from '@leafer-ui/draw'
3
3
  import { DragEvent, PointerEvent, KeyEvent, RotateEvent, ZoomEvent, MoveEvent } from '@leafer-ui/core'
4
4
 
5
5
  import { IEditBox, IEditor, IEditPoint, IEditPointType } from '@leafer-in/interface'
@@ -25,7 +25,7 @@ export class EditBox extends Group implements IEditBox {
25
25
 
26
26
  public view: IGroup = new Group() // 放置默认编辑工具控制点
27
27
 
28
- public rect: IBox = new Box({ name: 'rect', hitFill: 'all', hitStroke: 'none', strokeAlign: 'center', hitRadius: 5 }) // target rect
28
+ public rect: IEditPoint = new EditPoint({ name: 'rect', hitFill: 'all', hitStroke: 'none', strokeAlign: 'center', hitRadius: 5 }) // target rect
29
29
  public circle: IEditPoint = new EditPoint({ name: 'circle', strokeAlign: 'center', around: 'center', cursor: 'crosshair', hitRadius: 5 }) // rotate point
30
30
  public buttons: IGroup = new Group({ around: 'center', hitSelf: false, visible: 0 })
31
31
 
@@ -68,6 +68,7 @@ export class EditBox extends Group implements IEditBox {
68
68
  const { moveable, resizeable, rotateable } = this.mergeConfig
69
69
  return isString(moveable) || isString(resizeable) || isString(rotateable)
70
70
  }
71
+ public get canDragLimitAnimate(): boolean { return (this.moving && this.mergeConfig.dragLimitAnimate && this.target.dragBounds) as any as boolean }
71
72
 
72
73
  protected __eventIds: IEventListenerId[] = []
73
74
 
@@ -101,6 +102,7 @@ export class EditBox extends Group implements IEditBox {
101
102
  }
102
103
 
103
104
  this.listenPointEvents(circle, 'rotate', 2)
105
+ this.listenPointEvents(rect, 'move', 8) // center
104
106
 
105
107
  view.addMany(...rotatePoints, rect, circle, buttons, ...resizeLines, ...resizePoints)
106
108
  this.add(view)
@@ -108,8 +110,8 @@ export class EditBox extends Group implements IEditBox {
108
110
 
109
111
 
110
112
  public load(): void {
111
- const { target, mergeConfig, single, rect, circle, resizePoints } = this
112
- const { stroke, strokeWidth } = mergeConfig
113
+ const { target, mergeConfig, single, rect, circle, resizePoints, resizeLines } = this
114
+ const { stroke, strokeWidth, resizeLine } = mergeConfig
113
115
 
114
116
  const pointsStyle = this.getPointsStyle()
115
117
  const middlePointsStyle = this.getMiddlePointsStyle()
@@ -122,6 +124,7 @@ export class EditBox extends Group implements IEditBox {
122
124
  resizeP = resizePoints[i]
123
125
  resizeP.set(this.getPointStyle((i % 2) ? middlePointsStyle[((i - 1) / 2) % middlePointsStyle.length] : pointsStyle[(i / 2) % pointsStyle.length]))
124
126
  resizeP.rotation = ((i - (i % 2 ? 1 : 0)) / 2) * 90
127
+ if (i % 2) resizeLines[(i - 1) / 2].set({ pointType: 'resize', rotation: (i - 1) / 2 * 90, ...(resizeLine || {}) } as IEditPointInputData)
125
128
  }
126
129
 
127
130
  // rotate
@@ -159,12 +162,15 @@ export class EditBox extends Group implements IEditBox {
159
162
 
160
163
 
161
164
  public updateBounds(bounds: IBoundsData): void {
162
- const { editMask } = this.editor
163
- const { mergeConfig, single, rect, circle, buttons, resizePoints, rotatePoints, resizeLines } = this
164
- const { middlePoint, resizeable, rotateable, hideOnSmall, editBox, mask, spread, hideRotatePoints, hideResizeLines } = mergeConfig
165
+ const { editor, mergeConfig, single, rect, circle, buttons, resizePoints, rotatePoints, resizeLines } = this
166
+ const { editMask } = editor
167
+ const { middlePoint, resizeable, rotateable, hideOnSmall, editBox, mask, dimOthers, bright, spread, hideRotatePoints, hideResizeLines } = mergeConfig
165
168
 
166
169
  editMask.visible = mask ? true : 0
167
170
 
171
+ editor.setDimOthers(dimOthers)
172
+ editor.setBright(!!dimOthers || bright)
173
+
168
174
  if (spread) BoundsHelper.spread(bounds, spread)
169
175
 
170
176
  if (this.view.worldOpacity) {
@@ -195,10 +201,10 @@ export class EditBox extends Group implements IEditBox {
195
201
  resizeP.visible = rotateP.visible = showPoints && !!middlePoint
196
202
 
197
203
  if (((i + 1) / 2) % 2) { // top, bottom
198
- resizeL.width = width
204
+ resizeL.width = width + resizeL.height
199
205
  if (hideOnSmall && resizeP.width * 2 > width) resizeP.visible = false
200
206
  } else {
201
- resizeL.height = height
207
+ resizeL.width = height + resizeL.height
202
208
  if (hideOnSmall && resizeP.width * 2 > height) resizeP.visible = false
203
209
  }
204
210
  }
@@ -280,15 +286,14 @@ export class EditBox extends Group implements IEditBox {
280
286
 
281
287
  // drag
282
288
 
283
- protected onDragStart(e: DragEvent): void {
289
+ public onDragStart(e: DragEvent): void {
284
290
  this.dragging = true
285
291
  const point = this.dragPoint = e.current as IEditPoint, { pointType } = point
286
- const { editor, dragStartData } = this, { target } = this, { moveable, resizeable, rotateable, skewable, hideOnMove } = this.mergeConfig
292
+ const { moveable, resizeable, rotateable, skewable } = this.mergeConfig
287
293
 
288
294
  // 确定模式
289
- if (point.name === 'rect') {
295
+ if (pointType === 'move') {
290
296
  moveable && (this.moving = true)
291
- editor.opacity = hideOnMove ? 0 : 1 // move
292
297
  } else {
293
298
  if (pointType.includes('rotate') || this.isHoldRotateKey(e) || !resizeable) {
294
299
  rotateable && (this.rotating = true)
@@ -298,41 +303,54 @@ export class EditBox extends Group implements IEditBox {
298
303
  if (pointType === 'skew') skewable && (this.skewing = true)
299
304
  }
300
305
 
301
- dragStartData.x = e.x
302
- dragStartData.y = e.y
303
- dragStartData.point = { x: target.x, y: target.y } // 用于移动
304
- dragStartData.bounds = { ...target.getLayoutBounds('box', 'local') } // 用于resize
305
- dragStartData.rotation = target.rotation // 用于旋转
306
- if (pointType && pointType.includes('resize')) ResizeEvent.resizingKeys = editor.leafList.keys // 记录正在resize中的元素列表
307
- }
308
-
309
- protected onDragEnd(e: DragEvent): void {
310
- if (this.moving && this.mergeConfig.dragLimitAnimate && this.target.dragBounds) this.transformTool.onMove(e)
311
-
312
- this.dragPoint = null
313
- this.resetDoing()
314
- const { name, pointType } = e.current as IEditPoint
315
- if (name === 'rect') this.editor.opacity = 1 // move
316
- if (pointType && pointType.includes('resize')) ResizeEvent.resizingKeys = null
306
+ this.onTransformStart(e)
317
307
  }
318
308
 
319
- protected onDrag(e: DragEvent): void {
309
+ public onDrag(e: DragEvent): void {
320
310
  const { transformTool, moving, resizing, rotating, skewing } = this
321
311
  if (moving) {
322
312
  transformTool.onMove(e)
323
- updateMoveCursor(this)
324
313
  } else if (resizing || rotating || skewing) {
325
314
  const point = e.current as IEditPoint
326
315
  if (point.pointType) this.enterPoint = point// 防止变化
327
316
  if (rotating) transformTool.onRotate(e)
328
317
  if (resizing) transformTool.onScale(e)
329
318
  if (skewing) transformTool.onSkew(e)
330
- updatePointCursor(this, e)
319
+ }
320
+ updatePointCursor(this, e)
321
+ }
322
+
323
+ public onDragEnd(e: DragEvent): void {
324
+ this.onTransformEnd(e)
325
+ this.dragPoint = null
326
+ }
327
+
328
+ // 操作事件共用
329
+
330
+ public onTransformStart(e: IUIEvent): void {
331
+ if (this.canUse) {
332
+ if (this.moving) this.editor.opacity = this.mergedConfig.hideOnMove ? 0 : 1 // move
333
+ if (this.resizing) ResizeEvent.resizingKeys = this.editor.leafList.keys // 记录正在resize中的元素列表
334
+
335
+ const { dragStartData, target } = this
336
+ dragStartData.x = e.x
337
+ dragStartData.y = e.y
338
+ dragStartData.totalOffset = getPointData() // 缩放、旋转造成的总偏移量,一般用于手势操作的move纠正
339
+ dragStartData.point = { x: target.x, y: target.y } // 用于移动
340
+ dragStartData.bounds = { ...target.getLayoutBounds('box', 'local') } // 用于resize
341
+ dragStartData.rotation = target.rotation // 用于旋转
331
342
  }
332
343
  }
333
344
 
334
- protected resetDoing(): void {
335
- if (this.canUse) this.dragging = this.gesturing = this.moving = this.resizing = this.rotating = this.skewing = false
345
+ public onTransformEnd(e: IUIEvent): void {
346
+ if (this.canUse) {
347
+ if (this.canDragLimitAnimate && (e instanceof DragEvent || e instanceof MoveEvent)) this.transformTool.onMove(e)
348
+ if (this.resizing) ResizeEvent.resizingKeys = null
349
+
350
+ this.dragging = this.gesturing = this.moving = this.resizing = this.rotating = this.skewing = false
351
+ this.editor.opacity = 1
352
+ this.update() // 移动端手势操作hideOnMove移动需强制更新一次
353
+ }
336
354
  }
337
355
 
338
356
  // 手势控制元素
@@ -340,24 +358,19 @@ export class EditBox extends Group implements IEditBox {
340
358
  public onMove(e: MoveEvent): void {
341
359
  if (this.canGesture && e.moveType !== 'drag') {
342
360
  e.stop()
343
- if (isString(this.mergeConfig.moveable)) {
361
+ if (isString(this.mergedConfig.moveable)) {
344
362
  this.gesturing = this.moving = true
345
- this.transformTool.onMove(e)
363
+ e.type === MoveEvent.START ? this.onTransformStart(e) : this.transformTool.onMove(e)
346
364
  }
347
365
  }
348
366
  }
349
367
 
350
- public onMoveEnd(e: MoveEvent): void {
351
- if (this.moving) this.transformTool.onMove(e)
352
- this.resetDoing()
353
- }
354
-
355
368
  public onScale(e: ZoomEvent): void {
356
369
  if (this.canGesture) {
357
370
  e.stop()
358
- if (isString(this.mergeConfig.resizeable)) {
371
+ if (isString(this.mergedConfig.resizeable)) {
359
372
  this.gesturing = this.resizing = true
360
- this.transformTool.onScale(e)
373
+ e.type === ZoomEvent.START ? this.onTransformStart(e) : this.transformTool.onScale(e)
361
374
  }
362
375
  }
363
376
  }
@@ -365,14 +378,15 @@ export class EditBox extends Group implements IEditBox {
365
378
  public onRotate(e: RotateEvent): void {
366
379
  if (this.canGesture) {
367
380
  e.stop()
368
- if (isString(this.mergeConfig.rotateable)) {
381
+ if (isString(this.mergedConfig.rotateable)) {
369
382
  this.gesturing = this.rotating = true
370
- this.transformTool.onRotate(e)
383
+ e.type === RotateEvent.START ? this.onTransformStart(e) : this.transformTool.onRotate(e)
371
384
  }
372
385
  }
373
386
  }
374
387
 
375
388
  // 键盘
389
+
376
390
  public isHoldRotateKey(e: IUIEvent): boolean { // 按住ctrl在控制点上变旋转功能
377
391
  const { rotateKey } = this.mergedConfig
378
392
  if (rotateKey) return e.isHoldKeys(rotateKey)
@@ -384,8 +398,7 @@ export class EditBox extends Group implements IEditBox {
384
398
  }
385
399
 
386
400
  public onArrow(e: IKeyEvent): void {
387
- const { editor, transformTool } = this
388
- if (this.canUse && editor.editing && this.mergeConfig.keyEvent) {
401
+ if (this.canUse && this.mergeConfig.keyEvent) {
389
402
  let x = 0, y = 0
390
403
  const distance = e.shiftKey ? 10 : 1
391
404
  switch (e.code) {
@@ -401,7 +414,7 @@ export class EditBox extends Group implements IEditBox {
401
414
  case 'ArrowRight':
402
415
  x = distance
403
416
  }
404
- if (x || y) transformTool.move(x, y)
417
+ if (x || y) this.transformTool.move(x, y)
405
418
  }
406
419
  }
407
420
 
@@ -440,14 +453,16 @@ export class EditBox extends Group implements IEditBox {
440
453
  point.direction = direction
441
454
  point.pointType = type
442
455
 
443
- const events: IEventParams[] = [
444
- [DragEvent.START, this.onDragStart, this],
445
- [DragEvent.DRAG, this.onDrag, this],
446
- [DragEvent.END, this.onDragEnd, this],
447
- [PointerEvent.LEAVE, () => { this.enterPoint = null }],
448
- ]
449
- if (point.name !== 'circle') events.push([PointerEvent.ENTER, (e: PointerEvent) => { this.enterPoint = point, updatePointCursor(this, e) }])
450
- this.__eventIds.push(point.on_(events))
456
+ this.__eventIds.push(
457
+ point.on_([
458
+ [DragEvent.START, this.onDragStart, this],
459
+ [DragEvent.DRAG, this.onDrag, this],
460
+ [DragEvent.END, this.onDragEnd, this],
461
+
462
+ [PointerEvent.ENTER, (e: PointerEvent) => { this.enterPoint = point, updatePointCursor(this, e) }],
463
+ [PointerEvent.LEAVE, () => { this.enterPoint = null }]
464
+ ])
465
+ )
451
466
  }
452
467
 
453
468
  protected __listenEvents(): void {
@@ -455,11 +470,6 @@ export class EditBox extends Group implements IEditBox {
455
470
 
456
471
  events.push(
457
472
  rect.on_([
458
- [DragEvent.START, this.onDragStart, this],
459
- [DragEvent.DRAG, this.onDrag, this],
460
- [DragEvent.END, this.onDragEnd, this],
461
-
462
- [PointerEvent.ENTER, () => updateMoveCursor(this)],
463
473
  [PointerEvent.DOUBLE_TAP, this.onDoubleTap, this],
464
474
  [PointerEvent.LONG_PRESS, this.onLongPress, this]
465
475
  ])
@@ -470,12 +480,12 @@ export class EditBox extends Group implements IEditBox {
470
480
  editor.app.on_([
471
481
  [[KeyEvent.HOLD, KeyEvent.UP], this.onKey, this],
472
482
  [KeyEvent.DOWN, this.onArrow, this],
473
- [MoveEvent.BEFORE_MOVE, this.onMove, this, true],
474
- [ZoomEvent.BEFORE_ZOOM, this.onScale, this, true],
475
- [RotateEvent.BEFORE_ROTATE, this.onRotate, this, true],
476
- [MoveEvent.END, this.onMoveEnd, this],
477
- [ZoomEvent.END, this.resetDoing, this],
478
- [RotateEvent.END, this.resetDoing, this],
483
+
484
+ [[MoveEvent.START, MoveEvent.BEFORE_MOVE], this.onMove, this, true],
485
+ [[ZoomEvent.START, ZoomEvent.BEFORE_ZOOM], this.onScale, this, true],
486
+ [[RotateEvent.START, RotateEvent.BEFORE_ROTATE], this.onRotate, this, true],
487
+
488
+ [[MoveEvent.END, ZoomEvent.END, RotateEvent.END], this.onTransformEnd, this],
479
489
  ])
480
490
  )
481
491
  })
@@ -17,8 +17,8 @@ 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 { const { editor } = this; return this.hittable && editor.visible && editor.hittable && editor.mergeConfig.selector && this.app.mode === 'normal' }
21
- public get isMoveMode(): boolean { return this.app && this.app.interaction.moveMode }
20
+ public get running(): boolean { const { editor, app } = this; return this.hittable && editor.visible && editor.hittable && editor.mergeConfig.selector && (app && app.mode === 'normal') }
21
+ public get isMoveMode(): boolean { const { app } = this; return app && app.interaction.moveMode }
22
22
 
23
23
  public hoverStroker: IStroker = new Stroker()
24
24
  public targetStroker: IStroker = new Stroker()
@@ -95,7 +95,7 @@ export class EditSelect extends Group implements IEditSelect {
95
95
  if (e.multiTouch) return
96
96
 
97
97
  const { editor } = this
98
- const { select } = editor.mergeConfig
98
+ const { select, selectKeep } = editor.mergeConfig
99
99
 
100
100
  if (select === 'tap') this.checkAndSelect(e)
101
101
  else if (this.waitSelect) this.waitSelect()
@@ -103,7 +103,7 @@ export class EditSelect extends Group implements IEditSelect {
103
103
  if (this.needRemoveItem) {
104
104
  editor.removeItem(this.needRemoveItem)
105
105
  } else if (this.isMoveMode) {
106
- editor.target = null // move.dragEmpty
106
+ if (!selectKeep) editor.target = null // move.dragEmpty
107
107
  }
108
108
 
109
109
  }
@@ -125,7 +125,7 @@ export class EditSelect extends Group implements IEditSelect {
125
125
 
126
126
  } else if (this.allow(e.target)) {
127
127
 
128
- if (!this.isHoldMultipleSelectKey(e)) editor.target = null
128
+ if (!this.isHoldMultipleSelectKey(e) && !this.editor.mergedConfig.selectKeep) editor.target = null
129
129
 
130
130
  }
131
131
  }
@@ -11,15 +11,21 @@ const cacheCursors: IObject = {}
11
11
  export function updatePointCursor(editBox: IEditBox, e: IUIEvent): void {
12
12
  const { enterPoint: point, dragging, skewing, resizing, flippedX, flippedY } = editBox
13
13
  if (!point || !editBox.editor.editing || !editBox.canUse) return
14
+ if (point.name === 'rect') return updateMoveCursor(editBox) // rect 移动元素
14
15
  if (point.name === 'circle') return // 独立旋转按钮
15
- if (point.pointType === 'button') { // 普通按钮
16
+
17
+ let { rotation } = editBox
18
+ const { pointType } = point, { moveCursor, resizeCursor, rotateCursor, skewCursor, moveable, resizeable, rotateable, skewable } = editBox.mergeConfig
19
+
20
+ if (pointType === 'move') { // 移动类型
21
+ point.cursor = moveCursor
22
+ if (!moveable) point.visible = false
23
+ return
24
+ } else if (pointType === 'button') { // 普通按钮
16
25
  if (!point.cursor) point.cursor = 'pointer'
17
26
  return
18
27
  }
19
28
 
20
- let { rotation } = editBox
21
- const { pointType } = point, { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editBox.mergeConfig
22
-
23
29
  let showResize = pointType.includes('resize')
24
30
  if (showResize && rotateable && (editBox.isHoldRotateKey(e) || !resizeable)) showResize = false
25
31
  const showSkew = skewable && !showResize && (point.name === 'resize-line' || pointType === 'skew')
@@ -1,5 +1,5 @@
1
1
  import { IBoundsData, IPointData, IAround, IAlign, IUI, ILayoutBoundsData } from '@leafer-ui/interface'
2
- import { AroundHelper, MathHelper, PointHelper, Direction9, DragBoundsHelper } from '@leafer-ui/draw'
2
+ import { AroundHelper, MathHelper, PointHelper, Direction9, DragBoundsHelper, isNumber } from '@leafer-ui/draw'
3
3
 
4
4
  import { IEditorScaleEvent, IEditorSkewEvent, IEditorRotateEvent } from '@leafer-in/interface'
5
5
 
@@ -10,18 +10,12 @@ const { within, sign } = MathHelper
10
10
 
11
11
  export const EditDataHelper = {
12
12
 
13
- getScaleData(target: IUI, startBounds: ILayoutBoundsData, direction: Direction9, totalMove: IPointData, lockRatio: boolean | 'corner', around: IAround, flipable: boolean, scaleMode: boolean): IEditorScaleEvent {
13
+ getScaleData(target: IUI, startBounds: ILayoutBoundsData, direction: Direction9, totalMoveOrScale: IPointData | number, lockRatio: boolean | 'corner', around: IAround, flipable: boolean, scaleMode: boolean): IEditorScaleEvent {
14
14
  let align: IAlign, origin = {} as IPointData, scaleX: number = 1, scaleY: number = 1
15
15
 
16
16
  const { boxBounds, widthRange, heightRange, dragBounds, worldBoxBounds } = target
17
17
  const { width, height } = startBounds
18
18
 
19
- if (around) {
20
- totalMove.x *= 2
21
- totalMove.y *= 2
22
- }
23
-
24
-
25
19
  // 获取已经改变的比例
26
20
  const originChangedScaleX = target.scaleX / startBounds.scaleX
27
21
  const originChangedScaleY = target.scaleY / startBounds.scaleY
@@ -31,72 +25,85 @@ export const EditDataHelper = {
31
25
  const changedScaleX = scaleMode ? originChangedScaleX : signX * boxBounds.width / width
32
26
  const changedScaleY = scaleMode ? originChangedScaleY : signY * boxBounds.height / height
33
27
 
34
- totalMove.x *= scaleMode ? originChangedScaleX : signX
35
- totalMove.y *= scaleMode ? originChangedScaleY : signY
28
+ if (isNumber(totalMoveOrScale)) {
36
29
 
37
- const topScale = (-totalMove.y + height) / height
38
- const rightScale = (totalMove.x + width) / width
39
- const bottomScale = (totalMove.y + height) / height
40
- const leftScale = (-totalMove.x + width) / width
30
+ scaleX = scaleY = Math.sqrt(totalMoveOrScale)
41
31
 
42
- switch (direction) {
43
- case top:
44
- scaleY = topScale
45
- align = 'bottom'
46
- break
47
- case right:
48
- scaleX = rightScale
49
- align = 'left'
50
- break
51
- case bottom:
52
- scaleY = bottomScale
53
- align = 'top'
54
- break
55
- case left:
56
- scaleX = leftScale
57
- align = 'right'
58
- break
59
- case topLeft:
60
- scaleY = topScale
61
- scaleX = leftScale
62
- align = 'bottom-right'
63
- break
64
- case topRight:
65
- scaleY = topScale
66
- scaleX = rightScale
67
- align = 'bottom-left'
68
- break
69
- case bottomRight:
70
- scaleY = bottomScale
71
- scaleX = rightScale
72
- align = 'top-left'
73
- break
74
- case bottomLeft:
75
- scaleY = bottomScale
76
- scaleX = leftScale
77
- align = 'top-right'
78
- }
32
+ } else {
33
+
34
+ if (around) {
35
+ totalMoveOrScale.x *= 2
36
+ totalMoveOrScale.y *= 2
37
+ }
38
+
39
+ totalMoveOrScale.x *= scaleMode ? originChangedScaleX : signX
40
+ totalMoveOrScale.y *= scaleMode ? originChangedScaleY : signY
41
+
42
+ const topScale = (-totalMoveOrScale.y + height) / height
43
+ const rightScale = (totalMoveOrScale.x + width) / width
44
+ const bottomScale = (totalMoveOrScale.y + height) / height
45
+ const leftScale = (-totalMoveOrScale.x + width) / width
79
46
 
80
- if (lockRatio) {
81
- if (lockRatio === 'corner' && direction % 2) {
82
- lockRatio = false
83
- } else {
84
- let scale: number
85
- switch (direction) {
86
- case top:
87
- case bottom:
88
- scale = scaleY
89
- break
90
- case left:
91
- case right:
92
- scale = scaleX
93
- break
94
- default:
95
- scale = Math.sqrt(Math.abs(scaleX * scaleY))
47
+ switch (direction) {
48
+ case top:
49
+ scaleY = topScale
50
+ align = 'bottom'
51
+ break
52
+ case right:
53
+ scaleX = rightScale
54
+ align = 'left'
55
+ break
56
+ case bottom:
57
+ scaleY = bottomScale
58
+ align = 'top'
59
+ break
60
+ case left:
61
+ scaleX = leftScale
62
+ align = 'right'
63
+ break
64
+ case topLeft:
65
+ scaleY = topScale
66
+ scaleX = leftScale
67
+ align = 'bottom-right'
68
+ break
69
+ case topRight:
70
+ scaleY = topScale
71
+ scaleX = rightScale
72
+ align = 'bottom-left'
73
+ break
74
+ case bottomRight:
75
+ scaleY = bottomScale
76
+ scaleX = rightScale
77
+ align = 'top-left'
78
+ break
79
+ case bottomLeft:
80
+ scaleY = bottomScale
81
+ scaleX = leftScale
82
+ align = 'top-right'
83
+ }
84
+
85
+ if (lockRatio) {
86
+ if (lockRatio === 'corner' && direction % 2) {
87
+ lockRatio = false
88
+ } else {
89
+ let scale: number
90
+ switch (direction) {
91
+ case top:
92
+ case bottom:
93
+ scale = scaleY
94
+ break
95
+ case left:
96
+ case right:
97
+ scale = scaleX
98
+ break
99
+ default:
100
+ scale = Math.sqrt(Math.abs(scaleX * scaleY))
101
+ }
102
+ scaleX = scaleX < 0 ? -scale : scale
103
+ scaleY = scaleY < 0 ? -scale : scale
96
104
  }
97
- scaleX = scaleX < 0 ? -scale : scale
98
- scaleY = scaleY < 0 ? -scale : scale
99
105
  }
106
+
100
107
  }
101
108
 
102
109
  const useScaleX = scaleX !== 1, useScaleY = scaleY !== 1