@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.
- package/dist/editor.esm.js +462 -286
- package/dist/editor.esm.min.js +1 -1
- package/dist/editor.js +463 -285
- package/dist/editor.min.js +1 -1
- package/package.json +5 -5
- package/src/Editor.ts +114 -26
- package/src/config.ts +1 -0
- package/src/display/EditBox.ts +125 -70
- package/src/display/EditPoint.ts +3 -3
- package/src/display/EditSelect.ts +40 -35
- package/src/display/Stroker.ts +4 -4
- package/src/editor/cursor.ts +3 -3
- package/src/editor/target.ts +3 -1
- package/src/event/EditorScaleEvent.ts +3 -2
- package/src/helper/EditDataHelper.ts +8 -11
- package/src/index.ts +29 -6
- package/src/tool/EditTool.ts +36 -12
- package/src/tool/EditToolCreator.ts +32 -0
- package/src/tool/InnerEditor.ts +64 -0
- package/src/tool/LineEditTool.ts +8 -8
- package/types/index.d.ts +95 -42
- package/src/tool/index.ts +0 -21
package/src/display/EditBox.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { IRect, IAround, IEventListenerId, IBoundsData,
|
|
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,
|
|
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',
|
|
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
|
-
|
|
74
|
+
view.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints)
|
|
75
|
+
this.add(view)
|
|
73
76
|
}
|
|
74
77
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const {
|
|
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
|
|
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
|
-
|
|
95
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
// rect
|
|
98
|
+
rect.set({ stroke, strokeWidth, ...(mergeConfig.rect || {}) })
|
|
99
|
+
rect.hittable = !single && moveable
|
|
103
100
|
|
|
104
|
-
|
|
101
|
+
// 编辑框作为底部虚拟元素, 在 onSelect 方法移除
|
|
102
|
+
element.syncEventer = (single && moveable) ? rect : null
|
|
103
|
+
this.app.interaction.bottomList = (single && moveable) ? [{ target: rect, proxy: element }] : null
|
|
105
104
|
|
|
106
|
-
|
|
105
|
+
this.visible = !element.locked
|
|
106
|
+
}
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
circle.set(this.getPointStyle(config.rotatePoint || pointsStyle[0]))
|
|
150
|
+
// rotate
|
|
151
|
+
circle.visible = showPoints && rotateable && !!mergeConfig.rotatePoint
|
|
125
152
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
rect.set({ ...bounds, visible: true })
|
|
129
|
-
rect.hittable = config.moveable
|
|
153
|
+
// rect
|
|
154
|
+
rect.set({ ...bounds, visible: true })
|
|
130
155
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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.
|
|
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
|
|
171
|
-
|
|
172
|
-
|
|
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():
|
|
177
|
-
const { point } = this.editor.
|
|
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():
|
|
182
|
-
const { middlePoint } = this.editor.
|
|
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.
|
|
226
|
+
if (e.current.name === 'rect') {
|
|
227
|
+
const { editor } = this
|
|
191
228
|
this.moving = true
|
|
192
|
-
|
|
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.
|
|
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.
|
|
207
|
-
if (editor.
|
|
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.
|
|
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
|
-
|
|
269
|
+
this.editor.move(move)
|
|
232
270
|
}
|
|
233
271
|
}
|
|
234
272
|
|
|
235
|
-
|
|
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
|
|
238
|
-
|
|
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
|
-
|
|
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,
|
|
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.
|
|
315
|
+
rect.on_(PointerEvent.DOUBLE_TAP, this.onDoubleTap, this),
|
|
316
|
+
rect.on_(PointerEvent.LONG_PRESS, this.onLongPress, this)
|
|
262
317
|
]
|
|
263
318
|
}
|
|
264
319
|
|
package/src/display/EditPoint.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Box } from '@leafer-ui/draw'
|
|
1
|
+
import { Box, Direction9 } from '@leafer-ui/draw'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { IEditPoint, IEditPointType } from '@leafer-in/interface'
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
export class EditPoint extends Box implements IEditPoint {
|
|
7
|
-
public direction:
|
|
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 &&
|
|
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
|
|
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.
|
|
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.
|
|
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 =
|
|
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.
|
|
81
|
-
if (select === 'press') this.checkAndSelect(e
|
|
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
|
|
86
|
+
const { select } = editor.mergeConfig
|
|
87
87
|
if (select === 'tap') this.checkAndSelect(e)
|
|
88
88
|
|
|
89
|
-
if (this.
|
|
90
|
-
|
|
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
|
|
101
|
-
|
|
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.
|
|
102
|
+
const find = this.findUI(e)
|
|
104
103
|
|
|
105
104
|
if (find) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
editor.
|
|
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.
|
|
123
|
+
if (this.allowDrag(e)) {
|
|
131
124
|
const { editor } = this
|
|
132
|
-
const { stroke,
|
|
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,
|
|
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.
|
|
201
|
-
return (!this.editor.
|
|
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
|
|
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.
|
|
251
|
+
this.editor = this.originList = this.needRemoveItem = null
|
|
247
252
|
this.__removeListenEvents()
|
|
248
253
|
super.destroy()
|
|
249
254
|
}
|
package/src/display/Stroker.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
package/src/editor/cursor.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
39
|
+
editor.editBox.rect.cursor = editor.mergeConfig.moveCursor
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
|
package/src/editor/target.ts
CHANGED
|
@@ -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.
|
|
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 {
|
|
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:
|
|
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,
|
|
4
|
+
import { IEditorScaleEvent, IEditorSkewEvent, IEditorRotateEvent } from '@leafer-in/interface'
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
const { topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left } =
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
153
|
+
getFlipDirection(direction: Direction9, flipedX: boolean, flipedY: boolean): Direction9 {
|
|
157
154
|
if (flipedX) {
|
|
158
155
|
switch (direction) {
|
|
159
156
|
case left: direction = right; break
|