@leafer-in/editor 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editor.cjs +117 -83
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.esm.js +118 -84
- package/dist/editor.esm.js.map +1 -1
- package/dist/editor.esm.min.js +1 -1
- package/dist/editor.esm.min.js.map +1 -1
- package/dist/editor.js +117 -83
- package/dist/editor.js.map +1 -1
- 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 +5 -5
- package/src/Editor.ts +49 -26
- package/src/config.ts +1 -0
- package/src/display/EditBox.ts +28 -27
- package/src/display/EditSelect.ts +3 -3
- package/src/display/Stroker.ts +1 -1
- package/src/editor/cursor.ts +1 -1
- package/src/editor/simulate.ts +6 -1
- package/src/editor/target.ts +10 -2
- package/src/event/EditorGroupEvent.ts +6 -0
- package/src/event/EditorMoveEvent.ts +1 -0
- package/src/event/EditorRotateEvent.ts +1 -0
- package/src/event/EditorScaleEvent.ts +1 -0
- package/src/event/EditorSkewEvent.ts +1 -0
- package/src/helper/EditDataHelper.ts +5 -7
- package/src/index.ts +10 -36
- package/types/index.d.ts +14 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafer-in/editor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "@leafer-in/editor",
|
|
5
5
|
"author": "Chao (Leafer) Wan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"leaferjs"
|
|
35
35
|
],
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@leafer-ui/core": "^1.
|
|
38
|
-
"@leafer-in/resize": "^1.
|
|
39
|
-
"@leafer-ui/interface": "^1.
|
|
40
|
-
"@leafer-in/interface": "^1.
|
|
37
|
+
"@leafer-ui/core": "^1.5.0",
|
|
38
|
+
"@leafer-in/resize": "^1.5.0",
|
|
39
|
+
"@leafer-ui/interface": "^1.5.0",
|
|
40
|
+
"@leafer-in/interface": "^1.5.0"
|
|
41
41
|
}
|
|
42
42
|
}
|
package/src/Editor.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { IGroupInputData, IUI, IEventListenerId, IPointData, ILeafList, IEditSize, IGroup, IObject, IAlign, IAxis, IFunction,
|
|
2
|
-
import { Group, DataHelper, MathHelper, LeafList, Matrix, RenderEvent, LeafHelper, Direction9 } from '@leafer-ui/draw'
|
|
1
|
+
import { IGroupInputData, IUI, IEventListenerId, IPointData, ILeafList, IEditSize, IGroup, IObject, IAlign, IAxis, IFunction, IMatrix } from '@leafer-ui/interface'
|
|
2
|
+
import { Group, DataHelper, MathHelper, LeafList, Matrix, RenderEvent, LeafHelper, Direction9, isNull } from '@leafer-ui/draw'
|
|
3
3
|
import { DragEvent, RotateEvent, KeyEvent, ZoomEvent, MoveEvent, Plugin } from '@leafer-ui/core'
|
|
4
4
|
|
|
5
|
-
import { IEditBox, IEditPoint, IEditor, IEditorConfig, IEditTool, IEditorScaleEvent, IInnerEditor, ISimulateElement } from '@leafer-in/interface'
|
|
5
|
+
import { IEditBox, IEditPoint, IEditor, IEditorConfig, IEditTool, IEditorScaleEvent, IInnerEditor, ISimulateElement, IEditorMoveEvent, IEditorRotateEvent, IEditorSkewEvent } from '@leafer-in/interface'
|
|
6
6
|
|
|
7
7
|
import { EditorMoveEvent } from './event/EditorMoveEvent'
|
|
8
8
|
import { EditorScaleEvent } from './event/EditorScaleEvent'
|
|
@@ -32,8 +32,17 @@ export class Editor extends Group implements IEditor {
|
|
|
32
32
|
public config = DataHelper.clone(config) as IEditorConfig
|
|
33
33
|
|
|
34
34
|
public get mergeConfig(): IEditorConfig {
|
|
35
|
-
const { element,
|
|
36
|
-
|
|
35
|
+
const { config, element, dragPoint } = this, mergeConfig = { ...config } // 实时合并,后期可优化
|
|
36
|
+
if (element && element.editConfig) Object.assign(mergeConfig, element.editConfig)
|
|
37
|
+
if (dragPoint) {
|
|
38
|
+
if (dragPoint.editConfig) Object.assign(mergeConfig, dragPoint.editConfig)
|
|
39
|
+
if (mergeConfig.editSize === 'font-size') mergeConfig.lockRatio = true // 强制锁定比例
|
|
40
|
+
if (dragPoint.pointType === 'resize-rotate') {
|
|
41
|
+
mergeConfig.around || (mergeConfig.around = 'center')
|
|
42
|
+
isNull(mergeConfig.lockRatio) && (mergeConfig.lockRatio = true)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return mergeConfig
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
@targetAttr(onHover)
|
|
@@ -61,6 +70,7 @@ export class Editor extends Group implements IEditor {
|
|
|
61
70
|
|
|
62
71
|
public get dragging(): boolean { return this.editBox.dragging }
|
|
63
72
|
public get moving(): boolean { return this.editBox.moving }
|
|
73
|
+
public get dragPoint(): IEditPoint { return this.editBox.dragPoint }
|
|
64
74
|
|
|
65
75
|
// 组件
|
|
66
76
|
|
|
@@ -78,9 +88,6 @@ export class Editor extends Group implements IEditor {
|
|
|
78
88
|
public selector: EditSelect = new EditSelect(this)
|
|
79
89
|
public editMask: EditMask = new EditMask(this)
|
|
80
90
|
|
|
81
|
-
public dragStartPoint: IPointData
|
|
82
|
-
public dragStartBounds: ILayoutBoundsData
|
|
83
|
-
|
|
84
91
|
public targetEventIds: IEventListenerId[] = []
|
|
85
92
|
|
|
86
93
|
|
|
@@ -180,7 +187,7 @@ export class Editor extends Group implements IEditor {
|
|
|
180
187
|
else total.x = 0
|
|
181
188
|
}
|
|
182
189
|
|
|
183
|
-
this.move(DragEvent.getValidMove(this.element, this.
|
|
190
|
+
this.move(DragEvent.getValidMove(this.element, this.editBox.dragStartData.point, total))
|
|
184
191
|
|
|
185
192
|
}
|
|
186
193
|
|
|
@@ -200,7 +207,7 @@ export class Editor extends Group implements IEditor {
|
|
|
200
207
|
|
|
201
208
|
if (e.shiftKey || element.lockRatio) lockRatio = true
|
|
202
209
|
|
|
203
|
-
const data = EditDataHelper.getScaleData(element, this.
|
|
210
|
+
const data = EditDataHelper.getScaleData(element, this.editBox.dragStartData.bounds, direction, e.getInnerTotal(element), lockRatio, EditDataHelper.getAround(around, e.altKey), flipable, this.multiple || editSize === 'scale')
|
|
204
211
|
|
|
205
212
|
if (this.editTool.onScaleWithDrag) {
|
|
206
213
|
data.drag = e
|
|
@@ -218,7 +225,7 @@ export class Editor extends Group implements IEditor {
|
|
|
218
225
|
const { direction, name } = e.current as IEditPoint
|
|
219
226
|
if (skewable && name === 'resize-line') return this.onSkew(e as DragEvent)
|
|
220
227
|
|
|
221
|
-
const { element } = this
|
|
228
|
+
const { element } = this, { dragStartData } = this.editBox
|
|
222
229
|
let origin: IPointData, rotation: number
|
|
223
230
|
|
|
224
231
|
if (e instanceof RotateEvent) {
|
|
@@ -226,21 +233,23 @@ export class Editor extends Group implements IEditor {
|
|
|
226
233
|
if (rotateable === 'rotate') e.stop(), rotation = e.rotation, origin = element.getBoxPoint(e)
|
|
227
234
|
else return
|
|
228
235
|
|
|
236
|
+
if (element.scaleX * element.scaleY < 0) rotation = -rotation // flippedOne
|
|
237
|
+
|
|
229
238
|
} else {
|
|
230
239
|
|
|
231
|
-
const
|
|
232
|
-
const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getBoxPoint(element), element.getBoxPoint(last), e.shiftKey ? null : (element.around || element.origin || around || 'center'))
|
|
240
|
+
const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getBoxPoint(element), element.getBoxPoint(dragStartData), e.shiftKey ? null : (element.around || element.origin || around || 'center'))
|
|
233
241
|
rotation = data.rotation
|
|
234
242
|
origin = data.origin
|
|
235
243
|
|
|
236
244
|
}
|
|
237
245
|
|
|
238
|
-
rotation = MathHelper.getGapRotation(rotation, rotateGap, element.rotation)
|
|
239
|
-
if (!rotation) return
|
|
240
|
-
|
|
241
246
|
if (element.scaleX * element.scaleY < 0) rotation = -rotation // flippedOne
|
|
247
|
+
if (e instanceof DragEvent) rotation = dragStartData.rotation + rotation - element.rotation
|
|
242
248
|
|
|
243
|
-
|
|
249
|
+
rotation = MathHelper.float(MathHelper.getGapRotation(rotation, rotateGap, element.rotation), 2)
|
|
250
|
+
if (!rotation) return
|
|
251
|
+
|
|
252
|
+
this.rotateOf(origin, rotation)
|
|
244
253
|
}
|
|
245
254
|
|
|
246
255
|
|
|
@@ -261,11 +270,12 @@ export class Editor extends Group implements IEditor {
|
|
|
261
270
|
const { element } = this
|
|
262
271
|
if (!this.checkTransform('moveable')) return
|
|
263
272
|
|
|
264
|
-
|
|
265
273
|
const world = element.getWorldPointByLocal(typeof x === 'object' ? { ...x } : { x, y }, null, true)
|
|
266
274
|
if (this.multiple) element.safeChange(() => element.move(x, y))
|
|
267
|
-
const
|
|
275
|
+
const data: IEditorMoveEvent = { target: element, editor: this, moveX: world.x, moveY: world.y }
|
|
268
276
|
|
|
277
|
+
this.emitEvent(new EditorMoveEvent(EditorMoveEvent.BEFORE_MOVE, data))
|
|
278
|
+
const event = new EditorMoveEvent(EditorMoveEvent.MOVE, data)
|
|
269
279
|
this.editTool.onMove(event)
|
|
270
280
|
this.emitEvent(event)
|
|
271
281
|
}
|
|
@@ -274,8 +284,10 @@ export class Editor extends Group implements IEditor {
|
|
|
274
284
|
if (!this.checkTransform('resizeable')) return
|
|
275
285
|
|
|
276
286
|
const { element } = this
|
|
277
|
-
|
|
287
|
+
data = { ...data, target: element, editor: this, worldOrigin: element.getWorldPoint(data.origin) }
|
|
278
288
|
|
|
289
|
+
this.emitEvent(new EditorScaleEvent(EditorScaleEvent.BEFORE_SCALE, data))
|
|
290
|
+
const event = new EditorScaleEvent(EditorScaleEvent.SCALE, data)
|
|
279
291
|
this.editTool.onScaleWithDrag(event)
|
|
280
292
|
this.emitEvent(event)
|
|
281
293
|
}
|
|
@@ -287,8 +299,10 @@ export class Editor extends Group implements IEditor {
|
|
|
287
299
|
const { element } = this
|
|
288
300
|
const worldOrigin = this.getWorldOrigin(origin)
|
|
289
301
|
const transform = this.multiple && this.getChangedTransform(() => element.safeChange(() => element.scaleOf(origin, scaleX, scaleY)))
|
|
290
|
-
const
|
|
302
|
+
const data: IEditorScaleEvent = { target: element, editor: this, worldOrigin, scaleX, scaleY, transform }
|
|
291
303
|
|
|
304
|
+
this.emitEvent(new EditorScaleEvent(EditorScaleEvent.BEFORE_SCALE, data))
|
|
305
|
+
const event = new EditorScaleEvent(EditorScaleEvent.SCALE, data)
|
|
292
306
|
this.editTool.onScale(event)
|
|
293
307
|
this.emitEvent(event)
|
|
294
308
|
}
|
|
@@ -299,8 +313,10 @@ export class Editor extends Group implements IEditor {
|
|
|
299
313
|
const { element } = this
|
|
300
314
|
const worldOrigin = this.getWorldOrigin('center')
|
|
301
315
|
const transform = this.multiple ? this.getChangedTransform(() => element.safeChange(() => element.flip(axis))) : new Matrix(LeafHelper.getFlipTransform(element, axis))
|
|
302
|
-
const
|
|
316
|
+
const data: IEditorScaleEvent = { target: element, editor: this, worldOrigin, scaleX: axis === 'x' ? -1 : 1, scaleY: axis === 'y' ? -1 : 1, transform }
|
|
303
317
|
|
|
318
|
+
this.emitEvent(new EditorScaleEvent(EditorScaleEvent.BEFORE_SCALE, data))
|
|
319
|
+
const event = new EditorScaleEvent(EditorScaleEvent.SCALE, data)
|
|
304
320
|
this.editTool.onScale(event)
|
|
305
321
|
this.emitEvent(event)
|
|
306
322
|
}
|
|
@@ -311,8 +327,10 @@ export class Editor extends Group implements IEditor {
|
|
|
311
327
|
const { element } = this
|
|
312
328
|
const worldOrigin = this.getWorldOrigin(origin)
|
|
313
329
|
const transform = this.multiple && this.getChangedTransform(() => element.safeChange(() => element.rotateOf(origin, rotation)))
|
|
314
|
-
const
|
|
330
|
+
const data: IEditorRotateEvent = { target: element, editor: this, worldOrigin, rotation, transform }
|
|
315
331
|
|
|
332
|
+
this.emitEvent(new EditorRotateEvent(EditorRotateEvent.BEFORE_ROTATE, data))
|
|
333
|
+
const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, data)
|
|
316
334
|
this.editTool.onRotate(event)
|
|
317
335
|
this.emitEvent(event)
|
|
318
336
|
}
|
|
@@ -323,8 +341,10 @@ export class Editor extends Group implements IEditor {
|
|
|
323
341
|
const { element } = this
|
|
324
342
|
const worldOrigin = this.getWorldOrigin(origin)
|
|
325
343
|
const transform = this.multiple && this.getChangedTransform(() => element.safeChange(() => element.skewOf(origin, skewX, skewY)))
|
|
326
|
-
const
|
|
344
|
+
const data: IEditorSkewEvent = { target: element, editor: this, worldOrigin, skewX, skewY, transform }
|
|
327
345
|
|
|
346
|
+
this.emitEvent(new EditorSkewEvent(EditorSkewEvent.BEFORE_SKEW, data))
|
|
347
|
+
const event = new EditorSkewEvent(EditorSkewEvent.SKEW, data)
|
|
328
348
|
this.editTool.onSkew(event)
|
|
329
349
|
this.emitEvent(event)
|
|
330
350
|
}
|
|
@@ -349,6 +369,7 @@ export class Editor extends Group implements IEditor {
|
|
|
349
369
|
|
|
350
370
|
public group(userGroup?: IGroup | IGroupInputData): IGroup {
|
|
351
371
|
if (this.multiple) {
|
|
372
|
+
this.emitGroupEvent(EditorGroupEvent.BEFORE_GROUP)
|
|
352
373
|
this.target = EditorHelper.group(this.list, this.element, userGroup)
|
|
353
374
|
this.emitGroupEvent(EditorGroupEvent.GROUP, this.target as IGroup)
|
|
354
375
|
}
|
|
@@ -366,12 +387,14 @@ export class Editor extends Group implements IEditor {
|
|
|
366
387
|
}
|
|
367
388
|
|
|
368
389
|
public openGroup(group: IGroup): void {
|
|
390
|
+
this.emitGroupEvent(EditorGroupEvent.BEFORE_OPEN, group)
|
|
369
391
|
this.openedGroupList.add(group)
|
|
370
392
|
group.hitChildren = true
|
|
371
393
|
this.emitGroupEvent(EditorGroupEvent.OPEN, group)
|
|
372
394
|
}
|
|
373
395
|
|
|
374
396
|
public closeGroup(group: IGroup): void {
|
|
397
|
+
this.emitGroupEvent(EditorGroupEvent.BEFORE_CLOSE, group)
|
|
375
398
|
this.openedGroupList.remove(group)
|
|
376
399
|
group.hitChildren = false
|
|
377
400
|
this.emitGroupEvent(EditorGroupEvent.CLOSE, group)
|
|
@@ -398,10 +421,10 @@ export class Editor extends Group implements IEditor {
|
|
|
398
421
|
}
|
|
399
422
|
}
|
|
400
423
|
|
|
401
|
-
public emitGroupEvent(type: string, group
|
|
424
|
+
public emitGroupEvent(type: string, group?: IGroup): void {
|
|
402
425
|
const event = new EditorGroupEvent(type, { editTarget: group })
|
|
403
426
|
this.emitEvent(event)
|
|
404
|
-
group.emitEvent(event)
|
|
427
|
+
if (group) group.emitEvent(event)
|
|
405
428
|
}
|
|
406
429
|
|
|
407
430
|
// inner
|
package/src/config.ts
CHANGED
package/src/display/EditBox.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IRect, IEventListenerId, IBoundsData, IPointData, IKeyEvent, IGroup, IBox, IBoxInputData, IAlign, IUI, IEditorConfig } from '@leafer-ui/interface'
|
|
1
|
+
import { IRect, IEventListenerId, IBoundsData, IPointData, IKeyEvent, IGroup, IBox, IBoxInputData, IAlign, IUI, IEditorConfig, IEditorDragStartData } from '@leafer-ui/interface'
|
|
2
2
|
import { Group, Box, Text, AroundHelper, Direction9 } from '@leafer-ui/draw'
|
|
3
3
|
import { DragEvent, PointerEvent } from '@leafer-ui/core'
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ import { EditPoint } from './EditPoint'
|
|
|
10
10
|
import { EditDataHelper } from '../helper/EditDataHelper'
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
const fourDirection = ['top', 'right', 'bottom', 'left']
|
|
13
|
+
const fourDirection = ['top', 'right', 'bottom', 'left'], editConfig: IEditorConfig = undefined
|
|
14
14
|
|
|
15
15
|
export class EditBox extends Group implements IEditBox {
|
|
16
16
|
|
|
@@ -28,14 +28,17 @@ export class EditBox extends Group implements IEditBox {
|
|
|
28
28
|
public rotatePoints: IEditPoint[] = [] // topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left
|
|
29
29
|
public resizeLines: IEditPoint[] = [] // top, right, bottom, left
|
|
30
30
|
|
|
31
|
+
public enterPoint: IEditPoint
|
|
32
|
+
public dragPoint: IEditPoint // 正在拖拽的控制点
|
|
33
|
+
|
|
34
|
+
public dragStartData = {} as IEditorDragStartData
|
|
35
|
+
|
|
31
36
|
// fliped
|
|
32
37
|
public get flipped(): boolean { return this.flippedX || this.flippedY }
|
|
33
38
|
public get flippedX(): boolean { return this.scaleX < 0 }
|
|
34
39
|
public get flippedY(): boolean { return this.scaleY < 0 }
|
|
35
40
|
public get flippedOne(): boolean { return this.scaleX * this.scaleY < 0 }
|
|
36
41
|
|
|
37
|
-
public enterPoint: IEditPoint
|
|
38
|
-
|
|
39
42
|
protected __eventIds: IEventListenerId[] = []
|
|
40
43
|
|
|
41
44
|
constructor(editor: IEditor) {
|
|
@@ -93,7 +96,7 @@ export class EditBox extends Group implements IEditBox {
|
|
|
93
96
|
circle.set(this.getPointStyle(mergeConfig.circle || mergeConfig.rotatePoint || pointsStyle[0]))
|
|
94
97
|
|
|
95
98
|
// rect
|
|
96
|
-
rect.set({ stroke, strokeWidth, ...(mergeConfig.rect || {}) })
|
|
99
|
+
rect.set({ stroke, strokeWidth, editConfig, ...(mergeConfig.rect || {}) })
|
|
97
100
|
rect.hittable = !single
|
|
98
101
|
rect.syncEventer = single && this.editor // 单选下 rect 的事件不会冒泡,需要手动传递给editor
|
|
99
102
|
|
|
@@ -105,16 +108,16 @@ export class EditBox extends Group implements IEditBox {
|
|
|
105
108
|
}
|
|
106
109
|
|
|
107
110
|
public update(bounds: IBoundsData): void {
|
|
108
|
-
|
|
111
|
+
const { mergeConfig, element, multiple } = this.editor
|
|
112
|
+
const { middlePoint, resizeable, rotateable, hideOnSmall, editBox } = mergeConfig
|
|
113
|
+
this.visible = !element.locked
|
|
109
114
|
|
|
110
115
|
if (this.view.worldOpacity) {
|
|
111
|
-
const { mergeConfig } = this.editor
|
|
112
116
|
const { width, height } = bounds
|
|
113
117
|
const { rect, circle, buttons, resizePoints, rotatePoints, resizeLines } = this
|
|
114
|
-
const { middlePoint, resizeable, rotateable, hideOnSmall } = mergeConfig
|
|
115
118
|
|
|
116
119
|
const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10
|
|
117
|
-
const showPoints = !(hideOnSmall && width < smallSize && height < smallSize)
|
|
120
|
+
const showPoints = editBox && !(hideOnSmall && width < smallSize && height < smallSize)
|
|
118
121
|
|
|
119
122
|
let point = {} as IPointData, rotateP: IRect, resizeP: IRect, resizeL: IRect
|
|
120
123
|
|
|
@@ -138,11 +141,11 @@ export class EditBox extends Group implements IEditBox {
|
|
|
138
141
|
|
|
139
142
|
if (((i + 1) / 2) % 2) { // top, bottom
|
|
140
143
|
resizeL.width = width
|
|
141
|
-
if (resizeP.width > width
|
|
144
|
+
if (hideOnSmall && resizeP.width * 2 > width) resizeP.visible = false
|
|
142
145
|
} else {
|
|
143
146
|
resizeL.height = height
|
|
144
147
|
resizeP.rotation = 90
|
|
145
|
-
if (resizeP.width > height
|
|
148
|
+
if (hideOnSmall && resizeP.width * 2 > height) resizeP.visible = false
|
|
146
149
|
}
|
|
147
150
|
}
|
|
148
151
|
|
|
@@ -154,7 +157,7 @@ export class EditBox extends Group implements IEditBox {
|
|
|
154
157
|
|
|
155
158
|
// rect
|
|
156
159
|
if (rect.path) rect.path = null // line可能会变成path优先模式
|
|
157
|
-
rect.set({ ...bounds, visible: true })
|
|
160
|
+
rect.set({ ...bounds, visible: multiple ? true : editBox })
|
|
158
161
|
|
|
159
162
|
// buttons
|
|
160
163
|
buttons.visible = showPoints && buttons.children.length > 0
|
|
@@ -211,7 +214,7 @@ export class EditBox extends Group implements IEditBox {
|
|
|
211
214
|
|
|
212
215
|
public getPointStyle(userStyle?: IBoxInputData): IBoxInputData {
|
|
213
216
|
const { stroke, strokeWidth, pointFill, pointSize, pointRadius } = this.editor.mergeConfig
|
|
214
|
-
const defaultStyle = { fill: pointFill, stroke, strokeWidth, around: 'center', strokeAlign: 'center', width: pointSize, height: pointSize, cornerRadius: pointRadius, offsetX: 0, offsetY: 0 } as IBoxInputData
|
|
217
|
+
const defaultStyle = { fill: pointFill, stroke, strokeWidth, around: 'center', strokeAlign: 'center', width: pointSize, height: pointSize, cornerRadius: pointRadius, offsetX: 0, offsetY: 0, editConfig } as IBoxInputData
|
|
215
218
|
return userStyle ? Object.assign(defaultStyle, userStyle) : defaultStyle
|
|
216
219
|
}
|
|
217
220
|
|
|
@@ -236,33 +239,31 @@ export class EditBox extends Group implements IEditBox {
|
|
|
236
239
|
|
|
237
240
|
protected onDragStart(e: DragEvent): void {
|
|
238
241
|
this.dragging = true
|
|
239
|
-
const
|
|
240
|
-
|
|
242
|
+
const point = this.dragPoint = e.current as IEditPoint
|
|
243
|
+
const { editor, dragStartData } = this, { element } = editor
|
|
244
|
+
if (point.name === 'rect') {
|
|
241
245
|
this.moving = true
|
|
242
|
-
editor.dragStartPoint = { x: editor.element.x, y: editor.element.y }
|
|
243
246
|
editor.opacity = editor.mergeConfig.hideOnMove ? 0 : 1 // move
|
|
244
|
-
} else if ((e.current as IEditPoint).pointType === 'resize') {
|
|
245
|
-
editor.dragStartBounds = { ...editor.element.getLayoutBounds('box', 'local') }
|
|
246
|
-
editor.resizeDirection = (e.current as IEditPoint).direction
|
|
247
247
|
}
|
|
248
|
+
dragStartData.x = e.x
|
|
249
|
+
dragStartData.y = e.y
|
|
250
|
+
dragStartData.point = { x: element.x, y: element.y } // 用于移动
|
|
251
|
+
dragStartData.bounds = { ...element.getLayoutBounds('box', 'local') } // 用于resize
|
|
252
|
+
dragStartData.rotation = element.rotation // 用于旋转
|
|
248
253
|
}
|
|
249
254
|
|
|
250
255
|
protected onDragEnd(e: DragEvent): void {
|
|
251
256
|
this.dragging = false
|
|
257
|
+
this.dragPoint = null
|
|
252
258
|
this.moving = false
|
|
253
259
|
if (e.current.name === 'rect') this.editor.opacity = 1 // move
|
|
254
|
-
this.editor.resizeDirection = undefined
|
|
255
|
-
|
|
256
260
|
}
|
|
257
261
|
|
|
258
262
|
protected onDrag(e: DragEvent): void {
|
|
259
263
|
const { editor } = this
|
|
260
|
-
const
|
|
261
|
-
if (
|
|
262
|
-
|
|
263
|
-
} else if (point.pointType === 'resize') {
|
|
264
|
-
editor.onScale(e)
|
|
265
|
-
}
|
|
264
|
+
const { pointType } = this.enterPoint = e.current as IEditPoint
|
|
265
|
+
if (pointType.includes('rotate') || e.metaKey || e.ctrlKey || !editor.mergeConfig.resizeable) editor.onRotate(e)
|
|
266
|
+
if (pointType.includes('resize')) editor.onScale(e)
|
|
266
267
|
updateCursor(editor, e)
|
|
267
268
|
}
|
|
268
269
|
|
|
@@ -54,9 +54,9 @@ export class EditSelect extends Group implements IEditSelect {
|
|
|
54
54
|
|
|
55
55
|
protected onSelect(): void {
|
|
56
56
|
if (this.running) {
|
|
57
|
-
const { mergeConfig
|
|
58
|
-
const { stroke, strokeWidth } =
|
|
59
|
-
this.targetStroker.setTarget(list, { stroke, strokeWidth: Math.max(1, strokeWidth / 2) })
|
|
57
|
+
const { mergeConfig, list } = this.editor
|
|
58
|
+
const { stroke, strokeWidth, selectedStyle } = mergeConfig
|
|
59
|
+
this.targetStroker.setTarget(list, { stroke, strokeWidth: Math.max(1, strokeWidth / 2), ...(selectedStyle || {}) })
|
|
60
60
|
this.hoverStroker.target = null
|
|
61
61
|
}
|
|
62
62
|
}
|
package/src/display/Stroker.ts
CHANGED
|
@@ -54,7 +54,7 @@ export class Stroker extends UI implements IStroker {
|
|
|
54
54
|
leaf = list[i]
|
|
55
55
|
const { worldTransform, worldRenderBounds } = leaf
|
|
56
56
|
|
|
57
|
-
if (!bounds || bounds.hit(worldRenderBounds, options.matrix)) {
|
|
57
|
+
if (worldRenderBounds.width && worldRenderBounds.height && (!bounds || bounds.hit(worldRenderBounds, options.matrix))) {
|
|
58
58
|
|
|
59
59
|
const aScaleX = abs(worldTransform.scaleX), aScaleY = abs(worldTransform.scaleY)
|
|
60
60
|
|
package/src/editor/cursor.ts
CHANGED
|
@@ -21,7 +21,7 @@ export function updateCursor(editor: IEditor, e: IUIEvent): void {
|
|
|
21
21
|
const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig
|
|
22
22
|
const { pointType } = point, { flippedX, flippedY } = editBox
|
|
23
23
|
|
|
24
|
-
let showResize = pointType
|
|
24
|
+
let showResize = pointType.includes('resize')
|
|
25
25
|
if (showResize && rotateable && (e.metaKey || e.ctrlKey || !resizeable)) showResize = false
|
|
26
26
|
const showSkew = skewable && !showResize && point.name === 'resize-line'
|
|
27
27
|
|
package/src/editor/simulate.ts
CHANGED
|
@@ -9,6 +9,11 @@ const bounds = new Bounds()
|
|
|
9
9
|
export function simulate(editor: IEditor) {
|
|
10
10
|
const { simulateTarget, list } = editor
|
|
11
11
|
const { zoomLayer } = list[0].leafer.zoomLayer as IGroup // follow zoomLayer zoom / move
|
|
12
|
-
simulateTarget.safeChange(() =>
|
|
12
|
+
simulateTarget.safeChange(() => {
|
|
13
|
+
bounds.setListWithFn(list, (leaf: ILeaf) => leaf.getBounds('box', 'page'))
|
|
14
|
+
if (bounds.width === 0) bounds.width = 0.1 // fix
|
|
15
|
+
if (bounds.height === 0) bounds.height = 0.1
|
|
16
|
+
simulateTarget.reset(bounds.get())
|
|
17
|
+
})
|
|
13
18
|
zoomLayer.add(simulateTarget)
|
|
14
19
|
}
|
package/src/editor/target.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LeafList } from '@leafer-ui/draw'
|
|
2
2
|
|
|
3
|
-
import { IEditor, IUI } from '@leafer-in/interface'
|
|
3
|
+
import { IEditor, ILeaf, IUI } from '@leafer-in/interface'
|
|
4
4
|
|
|
5
5
|
import { simulate } from './simulate'
|
|
6
6
|
import { updateMoveCursor } from './cursor'
|
|
@@ -10,7 +10,11 @@ import { EditorEvent } from '../event/EditorEvent'
|
|
|
10
10
|
export function onTarget(editor: IEditor, oldValue: IUI | IUI[]): void {
|
|
11
11
|
const { target } = editor
|
|
12
12
|
if (target) {
|
|
13
|
-
editor.leafList = target instanceof LeafList ? target : new LeafList(target instanceof Array ? target : target as IUI)
|
|
13
|
+
const { list } = editor.leafList = target instanceof LeafList ? target : new LeafList(target instanceof Array ? target : target as IUI)
|
|
14
|
+
if (!list.every(checkEditable)) { // 过滤不合格的元素
|
|
15
|
+
editor.target = list.filter(checkEditable) as IUI[]
|
|
16
|
+
return
|
|
17
|
+
}
|
|
14
18
|
if (editor.multiple) simulate(editor) // 更新模拟元素
|
|
15
19
|
} else {
|
|
16
20
|
editor.simulateTarget.remove()
|
|
@@ -37,5 +41,9 @@ export function onTarget(editor: IEditor, oldValue: IUI | IUI[]): void {
|
|
|
37
41
|
|
|
38
42
|
export function onHover(editor: IEditor, oldValue: IUI): void {
|
|
39
43
|
editor.emitEvent(new EditorEvent(EditorEvent.HOVER, { editor, value: editor.hoverTarget, oldValue }))
|
|
44
|
+
}
|
|
45
|
+
|
|
40
46
|
|
|
47
|
+
function checkEditable(item: ILeaf): boolean {
|
|
48
|
+
return item.editable && !item.locked
|
|
41
49
|
}
|
|
@@ -7,11 +7,17 @@ import { } from '../tool/InnerEditor'
|
|
|
7
7
|
|
|
8
8
|
export class EditorGroupEvent extends EditorEvent implements IEditorGroupEvent {
|
|
9
9
|
|
|
10
|
+
|
|
11
|
+
static BEFORE_GROUP = 'editor.before_group'
|
|
10
12
|
static GROUP = 'editor.group'
|
|
13
|
+
|
|
11
14
|
static BEFORE_UNGROUP = 'editor.before_ungroup'
|
|
12
15
|
static UNGROUP = 'editor.ungroup'
|
|
13
16
|
|
|
17
|
+
static BEFORE_OPEN = 'editor.before_open_group'
|
|
14
18
|
static OPEN = 'editor.open_group'
|
|
19
|
+
|
|
20
|
+
static BEFORE_CLOSE = 'editor.before_close_group'
|
|
15
21
|
static CLOSE = 'editor.close_group'
|
|
16
22
|
|
|
17
23
|
readonly editTarget: IGroup
|
|
@@ -13,7 +13,7 @@ export const EditDataHelper = {
|
|
|
13
13
|
getScaleData(element: IUI, startBounds: ILayoutBoundsData, direction: Direction9, totalMove: IPointData, 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
|
-
const { boxBounds, widthRange, heightRange, dragBounds } = element
|
|
16
|
+
const { boxBounds, widthRange, heightRange, dragBounds, worldBoxBounds } = element
|
|
17
17
|
const { width, height } = startBounds
|
|
18
18
|
|
|
19
19
|
if (around) {
|
|
@@ -34,12 +34,6 @@ export const EditDataHelper = {
|
|
|
34
34
|
totalMove.x *= scaleMode ? originChangedScaleX : signX
|
|
35
35
|
totalMove.y *= scaleMode ? originChangedScaleY : signY
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
// 防止变为0
|
|
39
|
-
if (Math.abs(totalMove.x) === width) totalMove.x += 0.1
|
|
40
|
-
if (Math.abs(totalMove.y) === height) totalMove.y += 0.1
|
|
41
|
-
|
|
42
|
-
|
|
43
37
|
const topScale = (-totalMove.y + height) / height
|
|
44
38
|
const rightScale = (totalMove.x + width) / width
|
|
45
39
|
const bottomScale = (totalMove.y + height) / height
|
|
@@ -142,6 +136,10 @@ export const EditDataHelper = {
|
|
|
142
136
|
scaleY = within(nowHeight * scaleY, heightRange) / nowHeight
|
|
143
137
|
}
|
|
144
138
|
|
|
139
|
+
// 防止小于1px
|
|
140
|
+
if (Math.abs(scaleX * worldBoxBounds.width) < 1) scaleX = (scaleX < 0 ? -1 : 1) / worldBoxBounds.width
|
|
141
|
+
if (Math.abs(scaleY * worldBoxBounds.height) < 1) scaleY = (scaleY < 0 ? -1 : 1) / worldBoxBounds.height
|
|
142
|
+
|
|
145
143
|
return { origin, scaleX, scaleY, direction, lockRatio, around }
|
|
146
144
|
},
|
|
147
145
|
|
package/src/index.ts
CHANGED
|
@@ -26,7 +26,7 @@ export { EditSelectHelper } from './helper/EditSelectHelper'
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
import { IEditor, IEditorConfig, IEditToolFunction, IEditorConfigFunction } from '@leafer-in/interface'
|
|
29
|
-
import { Creator, UI, Group, Text, Box, dataType,
|
|
29
|
+
import { Creator, UI, Group, Text, Box, dataType, Plugin } from '@leafer-ui/draw'
|
|
30
30
|
|
|
31
31
|
import '@leafer-in/resize'
|
|
32
32
|
|
|
@@ -38,41 +38,15 @@ Plugin.add('editor', 'resize')
|
|
|
38
38
|
|
|
39
39
|
Creator.editor = function (options?: IEditorConfig): IEditor { return new Editor(options) }
|
|
40
40
|
|
|
41
|
+
Box.addAttr('textBox', false, dataType)
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
UI.addAttr('editConfig', undefined, dataType)
|
|
44
|
+
UI.addAttr('editOuter', (ui: UI) => ui.__.__isLinePath ? 'LineEditTool' : 'EditTool', dataType)
|
|
43
45
|
|
|
46
|
+
UI.addAttr('editInner', 'PathEditor', dataType)
|
|
47
|
+
Group.addAttr('editInner', '', dataType) // 必须设为空
|
|
48
|
+
Text.addAttr('editInner', 'TextEditor', dataType)
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
defineKey(UI.prototype, 'editInner', {
|
|
50
|
-
get(): string { return 'PathEditor' }
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
defineKey(Group.prototype, 'editInner', { // 必须设为空
|
|
54
|
-
get(): string { return '' }
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
defineKey(Text.prototype, 'editInner', {
|
|
58
|
-
get(): string { return 'TextEditor' }
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
UI.setEditConfig = function (config: IEditorConfig | IEditorConfigFunction): void {
|
|
63
|
-
defineKey(this.prototype, 'editConfig', {
|
|
64
|
-
get(): IEditorConfig { return typeof config === 'function' ? config(this) : config }
|
|
65
|
-
})
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
UI.setEditOuter = function (toolName: string | IEditToolFunction): void {
|
|
69
|
-
defineKey(this.prototype, 'editOuter', {
|
|
70
|
-
get(): string { return typeof toolName === 'string' ? toolName : toolName(this) }
|
|
71
|
-
})
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
UI.setEditInner = function (editorName: string | IEditToolFunction): void {
|
|
75
|
-
defineKey(this.prototype, 'editInner', {
|
|
76
|
-
get(): string { return typeof editorName === 'string' ? editorName : editorName(this) }
|
|
77
|
-
})
|
|
78
|
-
}
|
|
50
|
+
UI.setEditConfig = function (config: IEditorConfig | IEditorConfigFunction): void { this.changeAttr('editConfig', config) }
|
|
51
|
+
UI.setEditOuter = function (toolName: string | IEditToolFunction): void { this.changeAttr('editOuter', toolName) }
|
|
52
|
+
UI.setEditInner = function (editorName: string | IEditToolFunction): void { this.changeAttr('editInner', editorName) }
|