@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/dist/editor.cjs +200 -161
- package/dist/editor.esm.js +202 -163
- package/dist/editor.esm.min.js +1 -1
- package/dist/editor.esm.min.js.map +1 -1
- package/dist/editor.js +197 -158
- package/dist/editor.min.cjs +1 -1
- package/dist/editor.min.cjs.map +1 -1
- package/dist/editor.min.js +1 -1
- package/dist/editor.min.js.map +1 -1
- package/package.json +6 -6
- package/src/Editor.ts +19 -3
- package/src/decorator/data.ts +11 -6
- package/src/display/EditBox.ts +78 -68
- package/src/display/EditSelect.ts +5 -5
- package/src/editor/cursor.ts +10 -4
- package/src/helper/EditDataHelper.ts +76 -69
- package/src/tool/TransformTool.ts +35 -30
- package/types/index.d.ts +13 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafer-in/editor",
|
|
3
|
-
"version": "1.9.
|
|
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.
|
|
38
|
-
"@leafer-ui/core": "^1.9.
|
|
39
|
-
"@leafer-in/resize": "^1.9.
|
|
40
|
-
"@leafer-ui/interface": "^1.9.
|
|
41
|
-
"@leafer-in/interface": "^1.9.
|
|
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
|
-
|
|
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 {
|
package/src/decorator/data.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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:
|
|
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)
|
package/src/display/EditBox.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IRect, IEventListenerId, IBoundsData, IPointData, IKeyEvent, IGroup, IBox, IBoxInputData, IAlign, IUI, IEditorConfig, IEditorDragStartData,
|
|
2
|
-
import { Group,
|
|
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:
|
|
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 {
|
|
163
|
-
const {
|
|
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.
|
|
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
|
-
|
|
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 {
|
|
292
|
+
const { moveable, resizeable, rotateable, skewable } = this.mergeConfig
|
|
287
293
|
|
|
288
294
|
// 确定模式
|
|
289
|
-
if (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
335
|
-
if (this.canUse)
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
444
|
-
[
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
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
|
-
|
|
474
|
-
[
|
|
475
|
-
[
|
|
476
|
-
[
|
|
477
|
-
|
|
478
|
-
[RotateEvent.END, 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 &&
|
|
21
|
-
public get isMoveMode(): boolean { return
|
|
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
|
}
|
package/src/editor/cursor.ts
CHANGED
|
@@ -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
|
-
|
|
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,
|
|
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
|
-
|
|
35
|
-
totalMove.y *= scaleMode ? originChangedScaleY : signY
|
|
28
|
+
if (isNumber(totalMoveOrScale)) {
|
|
36
29
|
|
|
37
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|