@leafer-in/editor 1.0.0-rc.8 → 1.0.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 +1937 -0
- package/dist/editor.esm.js +1084 -412
- package/dist/editor.esm.min.js +1 -1
- package/dist/editor.js +1122 -441
- package/dist/editor.min.cjs +1 -0
- package/dist/editor.min.js +1 -1
- package/package.json +12 -7
- package/src/Editor.ts +231 -57
- package/src/config.ts +13 -4
- package/src/decorator/data.ts +1 -1
- package/src/display/EditBox.ts +147 -69
- package/src/display/EditMask.ts +37 -0
- package/src/display/EditPoint.ts +3 -3
- package/src/display/EditSelect.ts +61 -42
- package/src/display/SelectArea.ts +1 -1
- package/src/display/Stroker.ts +24 -21
- package/src/editor/cursor.ts +25 -38
- package/src/editor/simulate.ts +2 -2
- package/src/editor/target.ts +4 -2
- package/src/event/EditorEvent.ts +8 -1
- package/src/event/EditorGroupEvent.ts +23 -0
- package/src/event/EditorScaleEvent.ts +3 -2
- package/src/event/InnerEditorEvent.ts +23 -0
- package/src/helper/EditDataHelper.ts +66 -32
- package/src/helper/EditSelectHelper.ts +5 -4
- package/src/helper/EditorHelper.ts +11 -4
- package/src/index.ts +29 -5
- package/src/svg.ts +54 -0
- package/src/tool/EditTool.ts +51 -22
- package/src/tool/EditToolCreator.ts +32 -0
- package/src/tool/InnerEditor.ts +68 -0
- package/src/tool/LineEditTool.ts +94 -38
- package/types/index.d.ts +147 -49
- package/src/tool/index.ts +0 -21
package/src/display/Stroker.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IUI, ILeaferCanvas, IRenderOptions, IRectInputData } from '@leafer-ui/interface'
|
|
2
|
-
import { Paint, UI, MatrixHelper } from '@leafer-ui/
|
|
2
|
+
import { Paint, UI, MatrixHelper } from '@leafer-ui/draw'
|
|
3
3
|
|
|
4
4
|
import { IStroker } from '@leafer-in/interface'
|
|
5
5
|
|
|
@@ -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,40 +33,44 @@ 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++) {
|
|
41
40
|
leaf = list[i]
|
|
42
41
|
if (bounds && bounds.hit(leaf.__world, options.matrix)) {
|
|
43
42
|
|
|
44
|
-
|
|
43
|
+
const aScaleX = abs(leaf.__world.scaleX), aScaleY = abs(leaf.__world.scaleY)
|
|
45
44
|
|
|
46
|
-
if (
|
|
47
|
-
const aScaleX = abs(leaf.__world.scaleX), aScaleY = abs(leaf.__world.scaleY)
|
|
48
|
-
if (aScaleX !== aScaleY) { // need no scale stroke
|
|
49
|
-
copy(matrix, leaf.__world)
|
|
50
|
-
scale(matrix, 1 / aScaleX, 1 / aScaleY)
|
|
45
|
+
if (aScaleX !== aScaleY) { // need no scale stroke, use rect path
|
|
51
46
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
this.__.strokeWidth = strokeWidth
|
|
47
|
+
copy(matrix, leaf.__world)
|
|
48
|
+
scale(matrix, 1 / aScaleX, 1 / aScaleY)
|
|
55
49
|
|
|
56
|
-
|
|
57
|
-
|
|
50
|
+
canvas.setWorld(matrix, options.matrix)
|
|
51
|
+
canvas.beginPath()
|
|
52
|
+
this.__.strokeWidth = strokeWidth
|
|
58
53
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
const { x, y, width, height } = leaf.__layout.boxBounds
|
|
55
|
+
canvas.rect(x * aScaleX, y * aScaleY, width * aScaleX, height * aScaleY)
|
|
56
|
+
|
|
57
|
+
} else {
|
|
62
58
|
|
|
63
|
-
if (!drewPath) {
|
|
64
59
|
canvas.setWorld(leaf.__world, options.matrix)
|
|
65
60
|
canvas.beginPath()
|
|
66
|
-
|
|
61
|
+
|
|
62
|
+
if (leaf.__.__useArrow) {
|
|
63
|
+
leaf.__drawPath(canvas)
|
|
64
|
+
} else {
|
|
65
|
+
leaf.__.__pathForRender ? leaf.__drawRenderPath(canvas) : leaf.__drawPathByBox(canvas)
|
|
66
|
+
}
|
|
67
|
+
|
|
67
68
|
this.__.strokeWidth = strokeWidth / abs(leaf.__world.scaleX)
|
|
69
|
+
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
typeof stroke === 'string' ? Paint.stroke(stroke, this, canvas
|
|
72
|
+
if (stroke) typeof stroke === 'string' ? Paint.stroke(stroke, this, canvas) : Paint.strokes(stroke, this, canvas)
|
|
73
|
+
if (fill) typeof fill === 'string' ? Paint.fill(fill, this, canvas) : Paint.fills(fill, this, canvas)
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
76
|
|
package/src/editor/cursor.ts
CHANGED
|
@@ -1,58 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { IObject, IUIEvent } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
import { IEditor } from '@leafer-in/interface'
|
|
4
|
+
import { MathHelper } from '@leafer-ui/draw'
|
|
3
5
|
|
|
4
6
|
import { EditDataHelper } from '../helper/EditDataHelper'
|
|
5
7
|
|
|
6
8
|
|
|
7
|
-
const
|
|
9
|
+
const cacheCursors: IObject = {}
|
|
8
10
|
|
|
9
11
|
export function updateCursor(editor: IEditor, e: IUIEvent): void {
|
|
10
12
|
const { editBox } = editor, point = editBox.enterPoint
|
|
11
|
-
if (!point || !editor.
|
|
13
|
+
if (!point || !editor.editing || !editBox.visible) return
|
|
14
|
+
if (point.name === 'circle') return // 独立旋转按钮
|
|
12
15
|
|
|
13
16
|
let { rotation } = editBox
|
|
14
|
-
|
|
15
|
-
const {
|
|
17
|
+
const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig
|
|
18
|
+
const { pointType } = point, { flippedX, flippedY } = editBox
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
let showResize = pointType === 'resize'
|
|
21
|
+
if (showResize && rotateable && (e.metaKey || e.ctrlKey || !resizeable)) showResize = false
|
|
22
|
+
const showSkew = skewable && !showResize && point.name === 'resize-line'
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
const cursor = showSkew ? skewCursor : (showResize ? resizeCursor : rotateCursor)
|
|
25
|
+
rotation += (EditDataHelper.getFlipDirection(point.direction, flippedX, flippedY) + 1) * 45
|
|
26
|
+
rotation = Math.round(MathHelper.formatRotation(rotation, true) / 2) * 2
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
mirrorCursors(resizeCursor = [...resizeCursor], flippedX, flippedY)
|
|
25
|
-
mirrorCursors(rotateCursor = [...rotateCursor], flippedY, flippedX)
|
|
26
|
-
if (editBox.flippedOne) rotation = -rotation
|
|
27
|
-
}
|
|
28
|
+
const { url, x, y } = cursor
|
|
29
|
+
const key = url + rotation
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
if (cacheCursors[key]) {
|
|
32
|
+
point.cursor = cacheCursors[key]
|
|
33
|
+
} else {
|
|
34
|
+
cacheCursors[key] = point.cursor = { url: toDataURL(url, rotation), x, y }
|
|
35
|
+
}
|
|
31
36
|
}
|
|
32
37
|
|
|
33
38
|
export function updateMoveCursor(editor: IEditor): void {
|
|
34
|
-
editor.editBox.rect.cursor = editor.
|
|
39
|
+
editor.editBox.rect.cursor = editor.mergeConfig.moveCursor
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const topCursor = mirror[top], topLeftCursor = mirror[topLeft], topRightCursor = mirror[topRight]
|
|
41
|
-
mirror[top] = mirror[bottom]
|
|
42
|
-
mirror[topLeft] = mirror[bottomLeft]
|
|
43
|
-
mirror[topRight] = mirror[bottomRight]
|
|
44
|
-
mirror[bottom] = topCursor
|
|
45
|
-
mirror[bottomLeft] = topLeftCursor
|
|
46
|
-
mirror[bottomRight] = topRightCursor
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (mirrorY) {
|
|
50
|
-
const leftCursor = mirror[left], topLeftCursor = mirror[topLeft], bottomLeftCursor = mirror[bottomLeft]
|
|
51
|
-
mirror[left] = mirror[right]
|
|
52
|
-
mirror[topLeft] = mirror[topRight]
|
|
53
|
-
mirror[bottomLeft] = mirror[bottomRight]
|
|
54
|
-
mirror[right] = leftCursor
|
|
55
|
-
mirror[topRight] = topLeftCursor
|
|
56
|
-
mirror[bottomRight] = bottomLeftCursor
|
|
57
|
-
}
|
|
43
|
+
function toDataURL(svg: string, rotation: number): string {
|
|
44
|
+
return '"data:image/svg+xml,' + encodeURIComponent(svg.replace('{{rotation}}', rotation.toString())) + '"'
|
|
58
45
|
}
|
package/src/editor/simulate.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IGroup, ILeaf } from '@leafer-ui/interface'
|
|
2
|
-
import { Bounds } from '@leafer-ui/
|
|
2
|
+
import { Bounds } from '@leafer-ui/draw'
|
|
3
3
|
|
|
4
4
|
import { IEditor } from '@leafer-in/interface'
|
|
5
5
|
|
|
@@ -8,7 +8,7 @@ export function simulate(editor: IEditor) {
|
|
|
8
8
|
const { simulateTarget, leafList: targetList } = editor
|
|
9
9
|
const { x, y, width, height } = new Bounds().setListWithFn(targetList.list, (leaf: ILeaf) => leaf.worldBoxBounds)
|
|
10
10
|
|
|
11
|
-
const parent = simulateTarget.parent = targetList.list[0].leafer.zoomLayer as IGroup
|
|
11
|
+
const parent = simulateTarget.parent = targetList.list[0].leafer.zoomLayer as IGroup // follow zoomLayer zoom / move
|
|
12
12
|
const { scaleX, scaleY, e: worldX, f: worldY } = parent.__world
|
|
13
13
|
simulateTarget.reset({ x: (x - worldX) / scaleX, y: (y - worldY) / scaleY, width: width / scaleX, height: height / scaleY })
|
|
14
14
|
}
|
package/src/editor/target.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LeafList } from '@leafer-ui/
|
|
1
|
+
import { LeafList } from '@leafer-ui/draw'
|
|
2
2
|
|
|
3
3
|
import { IEditor, IUI } from '@leafer-in/interface'
|
|
4
4
|
|
|
@@ -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
|
}
|
package/src/event/EditorEvent.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { IUI, IPointData } from '@leafer-ui/interface'
|
|
2
|
-
import { Event } from '@leafer-ui/
|
|
2
|
+
import { Event } from '@leafer-ui/draw'
|
|
3
3
|
|
|
4
4
|
import { IEditor, IEditorEvent } from '@leafer-in/interface'
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
function toList(value: IUI | IUI[]): IUI[] {
|
|
8
|
+
return value ? (value instanceof Array ? value : [value]) : []
|
|
9
|
+
}
|
|
10
|
+
|
|
7
11
|
export class EditorEvent extends Event implements IEditorEvent {
|
|
8
12
|
|
|
9
13
|
static SELECT = 'editor.select'
|
|
@@ -15,6 +19,9 @@ export class EditorEvent extends Event implements IEditorEvent {
|
|
|
15
19
|
readonly value: IUI | IUI[]
|
|
16
20
|
readonly oldValue: IUI | IUI[]
|
|
17
21
|
|
|
22
|
+
get list() { return toList(this.value) }
|
|
23
|
+
get oldList() { return toList(this.oldValue) }
|
|
24
|
+
|
|
18
25
|
readonly worldOrigin: IPointData
|
|
19
26
|
declare readonly origin: IPointData
|
|
20
27
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { IEditorGroupEvent } from '@leafer-in/interface'
|
|
2
|
+
|
|
3
|
+
import { EditorEvent } from './EditorEvent'
|
|
4
|
+
import { IGroup } from '@leafer-ui/interface'
|
|
5
|
+
import { } from '../tool/InnerEditor'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export class EditorGroupEvent extends EditorEvent implements IEditorGroupEvent {
|
|
9
|
+
|
|
10
|
+
static GROUP = 'editor.group'
|
|
11
|
+
static BEFORE_UNGROUP = 'editor.before_ungroup'
|
|
12
|
+
static UNGROUP = 'editor.ungroup'
|
|
13
|
+
|
|
14
|
+
static OPEN = 'editor.open_group'
|
|
15
|
+
static CLOSE = 'editor.close_group'
|
|
16
|
+
|
|
17
|
+
readonly editTarget: IGroup
|
|
18
|
+
|
|
19
|
+
constructor(type: string, data?: IEditorGroupEvent) {
|
|
20
|
+
super(type, data)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
}
|
|
@@ -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
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { IInnerEditorEvent, IInnerEditor } from '@leafer-in/interface'
|
|
2
|
+
|
|
3
|
+
import { EditorEvent } from './EditorEvent'
|
|
4
|
+
import { IUI } from '@leafer-ui/interface'
|
|
5
|
+
import { } from '../tool/InnerEditor'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export class InnerEditorEvent extends EditorEvent implements IInnerEditorEvent {
|
|
9
|
+
|
|
10
|
+
static BEFORE_OPEN = 'innerEditor.before_open'
|
|
11
|
+
static OPEN = 'innerEditor.open'
|
|
12
|
+
|
|
13
|
+
static BEFORE_CLOSE = 'innerEditor.before_close'
|
|
14
|
+
static CLOSE = 'innerEditor.close'
|
|
15
|
+
|
|
16
|
+
readonly editTarget: IUI
|
|
17
|
+
readonly innerEditor: IInnerEditor
|
|
18
|
+
|
|
19
|
+
constructor(type: string, data?: IInnerEditorEvent) {
|
|
20
|
+
super(type, data)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { IBoundsData, IPointData, IAround } from '@leafer-ui/interface'
|
|
2
|
-
import { AroundHelper, PointHelper } from '@leafer-ui/
|
|
1
|
+
import { IBoundsData, IPointData, IAround, IAlign } from '@leafer-ui/interface'
|
|
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:
|
|
13
|
-
let
|
|
12
|
+
getScaleData(bounds: IBoundsData, direction: Direction9, pointMove: IPointData, lockRatio: boolean | 'corner', around: IAround): IEditorScaleEvent {
|
|
13
|
+
let align: IAlign, origin = {} as IPointData, scaleX: number = 1, scaleY: number = 1
|
|
14
14
|
const { width, height } = bounds
|
|
15
15
|
|
|
16
16
|
if (around) {
|
|
@@ -18,6 +18,10 @@ export const EditDataHelper = {
|
|
|
18
18
|
pointMove.y *= 2
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
// 防止变为0
|
|
22
|
+
if (Math.abs(pointMove.x) === width) pointMove.x += 0.1
|
|
23
|
+
if (Math.abs(pointMove.y) === height) pointMove.y += 0.1
|
|
24
|
+
|
|
21
25
|
const topScale = (-pointMove.y + height) / height
|
|
22
26
|
const rightScale = (pointMove.x + width) / width
|
|
23
27
|
const bottomScale = (pointMove.y + height) / height
|
|
@@ -26,99 +30,103 @@ export const EditDataHelper = {
|
|
|
26
30
|
switch (direction) {
|
|
27
31
|
case top:
|
|
28
32
|
scaleY = topScale
|
|
29
|
-
|
|
33
|
+
align = 'bottom'
|
|
30
34
|
break
|
|
31
35
|
case right:
|
|
32
36
|
scaleX = rightScale
|
|
33
|
-
|
|
37
|
+
align = 'left'
|
|
34
38
|
break
|
|
35
39
|
case bottom:
|
|
36
40
|
scaleY = bottomScale
|
|
37
|
-
|
|
41
|
+
align = 'top'
|
|
38
42
|
break
|
|
39
43
|
case left:
|
|
40
44
|
scaleX = leftScale
|
|
41
|
-
|
|
45
|
+
align = 'right'
|
|
42
46
|
break
|
|
43
47
|
case topLeft:
|
|
44
48
|
scaleY = topScale
|
|
45
49
|
scaleX = leftScale
|
|
46
|
-
|
|
50
|
+
align = 'bottom-right'
|
|
47
51
|
break
|
|
48
52
|
case topRight:
|
|
49
53
|
scaleY = topScale
|
|
50
54
|
scaleX = rightScale
|
|
51
|
-
|
|
55
|
+
align = 'bottom-left'
|
|
52
56
|
break
|
|
53
57
|
case bottomRight:
|
|
54
58
|
scaleY = bottomScale
|
|
55
59
|
scaleX = rightScale
|
|
56
|
-
|
|
60
|
+
align = 'top-left'
|
|
57
61
|
break
|
|
58
62
|
case bottomLeft:
|
|
59
63
|
scaleY = bottomScale
|
|
60
64
|
scaleX = leftScale
|
|
61
|
-
|
|
65
|
+
align = 'top-right'
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
if (lockRatio) {
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
const unlockSide = lockRatio === 'corner' && direction % 2
|
|
70
|
+
if (!unlockSide) {
|
|
71
|
+
const scale = Math.sqrt(Math.abs(scaleX * scaleY))
|
|
72
|
+
scaleX = scaleX < 0 ? -scale : scale
|
|
73
|
+
scaleY = scaleY < 0 ? -scale : scale
|
|
74
|
+
}
|
|
67
75
|
}
|
|
68
76
|
|
|
69
|
-
toPoint(around ||
|
|
77
|
+
toPoint(around || align, bounds, origin)
|
|
70
78
|
|
|
71
79
|
return { origin, scaleX, scaleY, direction, lockRatio, around }
|
|
72
80
|
},
|
|
73
81
|
|
|
74
|
-
getRotateData(bounds: IBoundsData, direction:
|
|
75
|
-
let
|
|
82
|
+
getRotateData(bounds: IBoundsData, direction: Direction9, current: IPointData, last: IPointData, around: IAround): IEditorRotateEvent {
|
|
83
|
+
let align: IAlign, origin = {} as IPointData
|
|
76
84
|
|
|
77
85
|
switch (direction) {
|
|
78
86
|
case topLeft:
|
|
79
|
-
|
|
87
|
+
align = 'bottom-right'
|
|
80
88
|
break
|
|
81
89
|
case topRight:
|
|
82
|
-
|
|
90
|
+
align = 'bottom-left'
|
|
83
91
|
break
|
|
84
92
|
case bottomRight:
|
|
85
|
-
|
|
93
|
+
align = 'top-left'
|
|
86
94
|
break
|
|
87
95
|
case bottomLeft:
|
|
88
|
-
|
|
96
|
+
align = 'top-right'
|
|
89
97
|
break
|
|
90
98
|
default:
|
|
91
|
-
|
|
99
|
+
align = 'center'
|
|
92
100
|
}
|
|
93
101
|
|
|
94
|
-
toPoint(around ||
|
|
102
|
+
toPoint(around || align, bounds, origin)
|
|
95
103
|
|
|
96
104
|
return { origin, rotation: PointHelper.getRotation(last, origin, current) }
|
|
97
105
|
},
|
|
98
106
|
|
|
99
|
-
getSkewData(bounds: IBoundsData, direction:
|
|
100
|
-
let
|
|
107
|
+
getSkewData(bounds: IBoundsData, direction: Direction9, move: IPointData, around: IAround): IEditorSkewEvent {
|
|
108
|
+
let align: IAlign, origin = {} as IPointData, skewX = 0, skewY = 0
|
|
101
109
|
let last: IPointData
|
|
102
110
|
|
|
103
111
|
switch (direction) {
|
|
104
112
|
case top:
|
|
105
113
|
last = { x: 0.5, y: 0 }
|
|
106
|
-
|
|
114
|
+
align = 'bottom'
|
|
107
115
|
skewX = 1
|
|
108
116
|
break
|
|
109
117
|
case bottom:
|
|
110
118
|
last = { x: 0.5, y: 1 }
|
|
111
|
-
|
|
119
|
+
align = 'top'
|
|
112
120
|
skewX = 1
|
|
113
121
|
break
|
|
114
122
|
case left:
|
|
115
123
|
last = { x: 0, y: 0.5 }
|
|
116
|
-
|
|
124
|
+
align = 'right'
|
|
117
125
|
skewY = 1
|
|
118
126
|
break
|
|
119
127
|
case right:
|
|
120
128
|
last = { x: 1, y: 0.5 }
|
|
121
|
-
|
|
129
|
+
align = 'left'
|
|
122
130
|
skewY = 1
|
|
123
131
|
}
|
|
124
132
|
|
|
@@ -127,7 +135,7 @@ export const EditDataHelper = {
|
|
|
127
135
|
last.x = x + last.x * width
|
|
128
136
|
last.y = y + last.y * height
|
|
129
137
|
|
|
130
|
-
toPoint(around ||
|
|
138
|
+
toPoint(around || align, bounds, origin)
|
|
131
139
|
|
|
132
140
|
const rotation = PointHelper.getRotation(last, origin, { x: last.x + (skewX ? move.x : 0), y: last.y + (skewY ? move.y : 0) })
|
|
133
141
|
skewX ? skewX = -rotation : skewY = rotation
|
|
@@ -143,6 +151,32 @@ export const EditDataHelper = {
|
|
|
143
151
|
getRotateDirection(direction: number, rotation: number, totalDirection = 8): number {
|
|
144
152
|
direction = (direction + Math.round(rotation / (360 / totalDirection))) % totalDirection
|
|
145
153
|
if (direction < 0) direction += totalDirection
|
|
154
|
+
return direction
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
getFlipDirection(direction: Direction9, flipedX: boolean, flipedY: boolean): Direction9 {
|
|
158
|
+
if (flipedX) {
|
|
159
|
+
switch (direction) {
|
|
160
|
+
case left: direction = right; break
|
|
161
|
+
case topLeft: direction = topRight; break
|
|
162
|
+
case bottomLeft: direction = bottomRight; break
|
|
163
|
+
case right: direction = left; break
|
|
164
|
+
case topRight: direction = topLeft; break
|
|
165
|
+
case bottomRight: direction = bottomLeft; break
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (flipedY) {
|
|
170
|
+
switch (direction) {
|
|
171
|
+
case top: direction = bottom; break
|
|
172
|
+
case topLeft: direction = bottomLeft; break
|
|
173
|
+
case topRight: direction = bottomRight; break
|
|
174
|
+
case bottom: direction = top; break
|
|
175
|
+
case bottomLeft: direction = topLeft; break
|
|
176
|
+
case bottomRight: direction = topRight; break
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
146
180
|
return direction
|
|
147
181
|
}
|
|
148
182
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IBounds, ILeafList, IUI } from '@leafer-ui/interface'
|
|
2
|
+
import { Answer } from '@leafer-ui/draw'
|
|
2
3
|
|
|
3
|
-
const { No, Yes, NoAndSkip, YesAndSkip } =
|
|
4
|
+
const { No, Yes, NoAndSkip, YesAndSkip } = Answer
|
|
4
5
|
|
|
5
6
|
export const EditSelectHelper = {
|
|
6
7
|
|
|
@@ -8,8 +9,8 @@ export const EditSelectHelper = {
|
|
|
8
9
|
return path.list.find((leaf) => leaf.editable) as IUI
|
|
9
10
|
},
|
|
10
11
|
|
|
11
|
-
findBounds(leaf: IUI, bounds: IBounds):
|
|
12
|
-
if (leaf.__.hittable && !leaf.__.locked && bounds.hit(leaf.__world)) {
|
|
12
|
+
findBounds(leaf: IUI, bounds: IBounds): Answer {
|
|
13
|
+
if (leaf.__.hittable && leaf.__.visible && !leaf.__.locked && bounds.hit(leaf.__world)) {
|
|
13
14
|
|
|
14
15
|
if (leaf.__.editable) {
|
|
15
16
|
if (leaf.isBranch && !leaf.__.hitChildren) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IGroup, ILeaf, IUI } from '@leafer-ui/interface'
|
|
2
|
-
import { Group, Matrix } from '@leafer-ui/
|
|
1
|
+
import { IGroup, IGroupInputData, ILeaf, IUI } from '@leafer-ui/interface'
|
|
2
|
+
import { Group, Matrix } from '@leafer-ui/draw'
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
const order = (a: ILeaf, b: ILeaf) => a.parent.children.indexOf(a) - b.parent.children.indexOf(b)
|
|
@@ -7,10 +7,17 @@ const reverseOrder = (a: ILeaf, b: ILeaf) => b.parent.children.indexOf(b) - a.pa
|
|
|
7
7
|
|
|
8
8
|
export const EditorHelper = {
|
|
9
9
|
|
|
10
|
-
group(list: IUI[], element?: IUI,
|
|
10
|
+
group(list: IUI[], element?: IUI, userGroup?: IGroup | IGroupInputData): IGroup {
|
|
11
11
|
list.sort(reverseOrder)
|
|
12
12
|
const { app, parent } = list[0]
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
let group: IGroup
|
|
15
|
+
if (userGroup && (userGroup as IGroup).add) {
|
|
16
|
+
group = userGroup as IGroup
|
|
17
|
+
} else {
|
|
18
|
+
group = new Group(userGroup)
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
parent.addAt(group, parent.children.indexOf(list[0]))
|
|
15
22
|
list.sort(order)
|
|
16
23
|
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export * from '@leafer-in/resize'
|
|
2
|
+
|
|
1
3
|
export { Editor } from './Editor'
|
|
2
4
|
|
|
3
5
|
export { EditBox } from './display/EditBox'
|
|
@@ -6,23 +8,45 @@ export { EditSelect } from './display/EditSelect'
|
|
|
6
8
|
export { SelectArea } from './display/SelectArea'
|
|
7
9
|
export { Stroker } from './display/Stroker'
|
|
8
10
|
|
|
11
|
+
|
|
9
12
|
export { EditorEvent } from './event/EditorEvent'
|
|
10
13
|
export { EditorMoveEvent } from './event/EditorMoveEvent'
|
|
11
14
|
export { EditorScaleEvent } from './event/EditorScaleEvent'
|
|
12
15
|
export { EditorRotateEvent } from './event/EditorRotateEvent'
|
|
13
16
|
export { EditorSkewEvent } from './event/EditorSkewEvent'
|
|
17
|
+
export { EditorGroupEvent } from './event/EditorGroupEvent'
|
|
18
|
+
export { InnerEditorEvent } from './event/InnerEditorEvent'
|
|
14
19
|
|
|
15
|
-
export {
|
|
20
|
+
export { EditToolCreator, registerEditTool, registerInnerEditor } from './tool/EditToolCreator'
|
|
21
|
+
export { InnerEditor } from './tool/InnerEditor'
|
|
16
22
|
export { EditTool } from './tool/EditTool'
|
|
23
|
+
export { LineEditTool } from './tool/LineEditTool'
|
|
17
24
|
|
|
18
25
|
export { EditorHelper } from './helper/EditorHelper'
|
|
19
26
|
export { EditDataHelper } from './helper/EditDataHelper'
|
|
20
27
|
export { EditSelectHelper } from './helper/EditSelectHelper'
|
|
21
28
|
|
|
22
|
-
import { IEditor, IEditorConfig } from '@leafer-in/interface'
|
|
23
|
-
import { Creator } from '@leafer-ui/
|
|
29
|
+
import { IEditor, IEditorConfig, IEditToolFunction, IEditorConfigFunction } from '@leafer-in/interface'
|
|
30
|
+
import { Creator, UI, defineKey } from '@leafer-ui/draw'
|
|
31
|
+
|
|
24
32
|
import { Editor } from './Editor'
|
|
25
33
|
|
|
26
|
-
Creator.editor = function (options?: IEditorConfig): IEditor {
|
|
27
|
-
|
|
34
|
+
Creator.editor = function (options?: IEditorConfig): IEditor { return new Editor(options) }
|
|
35
|
+
|
|
36
|
+
UI.setEditConfig = function (config: IEditorConfig | IEditorConfigFunction): void {
|
|
37
|
+
defineKey(this.prototype, 'editConfig', {
|
|
38
|
+
get(): IEditorConfig { return typeof config === 'function' ? config(this) : config }
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
UI.setEditOuter = function (toolName: string | IEditToolFunction): void {
|
|
43
|
+
defineKey(this.prototype, 'editOuter', {
|
|
44
|
+
get(): string { return typeof toolName === 'string' ? toolName : toolName(this) }
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
UI.setEditInner = function (editorName: string | IEditToolFunction): void {
|
|
49
|
+
defineKey(this.prototype, 'editInner', {
|
|
50
|
+
get(): string { return typeof editorName === 'string' ? editorName : editorName(this) }
|
|
51
|
+
})
|
|
28
52
|
}
|