@leafer-in/editor 1.0.0-rc.9 → 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 +1080 -412
- package/dist/editor.esm.min.js +1 -1
- package/dist/editor.js +1118 -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 +62 -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) {
|
|
@@ -30,99 +30,103 @@ export const EditDataHelper = {
|
|
|
30
30
|
switch (direction) {
|
|
31
31
|
case top:
|
|
32
32
|
scaleY = topScale
|
|
33
|
-
|
|
33
|
+
align = 'bottom'
|
|
34
34
|
break
|
|
35
35
|
case right:
|
|
36
36
|
scaleX = rightScale
|
|
37
|
-
|
|
37
|
+
align = 'left'
|
|
38
38
|
break
|
|
39
39
|
case bottom:
|
|
40
40
|
scaleY = bottomScale
|
|
41
|
-
|
|
41
|
+
align = 'top'
|
|
42
42
|
break
|
|
43
43
|
case left:
|
|
44
44
|
scaleX = leftScale
|
|
45
|
-
|
|
45
|
+
align = 'right'
|
|
46
46
|
break
|
|
47
47
|
case topLeft:
|
|
48
48
|
scaleY = topScale
|
|
49
49
|
scaleX = leftScale
|
|
50
|
-
|
|
50
|
+
align = 'bottom-right'
|
|
51
51
|
break
|
|
52
52
|
case topRight:
|
|
53
53
|
scaleY = topScale
|
|
54
54
|
scaleX = rightScale
|
|
55
|
-
|
|
55
|
+
align = 'bottom-left'
|
|
56
56
|
break
|
|
57
57
|
case bottomRight:
|
|
58
58
|
scaleY = bottomScale
|
|
59
59
|
scaleX = rightScale
|
|
60
|
-
|
|
60
|
+
align = 'top-left'
|
|
61
61
|
break
|
|
62
62
|
case bottomLeft:
|
|
63
63
|
scaleY = bottomScale
|
|
64
64
|
scaleX = leftScale
|
|
65
|
-
|
|
65
|
+
align = 'top-right'
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
if (lockRatio) {
|
|
69
|
-
|
|
70
|
-
|
|
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
|
+
}
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
toPoint(around ||
|
|
77
|
+
toPoint(around || align, bounds, origin)
|
|
74
78
|
|
|
75
79
|
return { origin, scaleX, scaleY, direction, lockRatio, around }
|
|
76
80
|
},
|
|
77
81
|
|
|
78
|
-
getRotateData(bounds: IBoundsData, direction:
|
|
79
|
-
let
|
|
82
|
+
getRotateData(bounds: IBoundsData, direction: Direction9, current: IPointData, last: IPointData, around: IAround): IEditorRotateEvent {
|
|
83
|
+
let align: IAlign, origin = {} as IPointData
|
|
80
84
|
|
|
81
85
|
switch (direction) {
|
|
82
86
|
case topLeft:
|
|
83
|
-
|
|
87
|
+
align = 'bottom-right'
|
|
84
88
|
break
|
|
85
89
|
case topRight:
|
|
86
|
-
|
|
90
|
+
align = 'bottom-left'
|
|
87
91
|
break
|
|
88
92
|
case bottomRight:
|
|
89
|
-
|
|
93
|
+
align = 'top-left'
|
|
90
94
|
break
|
|
91
95
|
case bottomLeft:
|
|
92
|
-
|
|
96
|
+
align = 'top-right'
|
|
93
97
|
break
|
|
94
98
|
default:
|
|
95
|
-
|
|
99
|
+
align = 'center'
|
|
96
100
|
}
|
|
97
101
|
|
|
98
|
-
toPoint(around ||
|
|
102
|
+
toPoint(around || align, bounds, origin)
|
|
99
103
|
|
|
100
104
|
return { origin, rotation: PointHelper.getRotation(last, origin, current) }
|
|
101
105
|
},
|
|
102
106
|
|
|
103
|
-
getSkewData(bounds: IBoundsData, direction:
|
|
104
|
-
let
|
|
107
|
+
getSkewData(bounds: IBoundsData, direction: Direction9, move: IPointData, around: IAround): IEditorSkewEvent {
|
|
108
|
+
let align: IAlign, origin = {} as IPointData, skewX = 0, skewY = 0
|
|
105
109
|
let last: IPointData
|
|
106
110
|
|
|
107
111
|
switch (direction) {
|
|
108
112
|
case top:
|
|
109
113
|
last = { x: 0.5, y: 0 }
|
|
110
|
-
|
|
114
|
+
align = 'bottom'
|
|
111
115
|
skewX = 1
|
|
112
116
|
break
|
|
113
117
|
case bottom:
|
|
114
118
|
last = { x: 0.5, y: 1 }
|
|
115
|
-
|
|
119
|
+
align = 'top'
|
|
116
120
|
skewX = 1
|
|
117
121
|
break
|
|
118
122
|
case left:
|
|
119
123
|
last = { x: 0, y: 0.5 }
|
|
120
|
-
|
|
124
|
+
align = 'right'
|
|
121
125
|
skewY = 1
|
|
122
126
|
break
|
|
123
127
|
case right:
|
|
124
128
|
last = { x: 1, y: 0.5 }
|
|
125
|
-
|
|
129
|
+
align = 'left'
|
|
126
130
|
skewY = 1
|
|
127
131
|
}
|
|
128
132
|
|
|
@@ -131,7 +135,7 @@ export const EditDataHelper = {
|
|
|
131
135
|
last.x = x + last.x * width
|
|
132
136
|
last.y = y + last.y * height
|
|
133
137
|
|
|
134
|
-
toPoint(around ||
|
|
138
|
+
toPoint(around || align, bounds, origin)
|
|
135
139
|
|
|
136
140
|
const rotation = PointHelper.getRotation(last, origin, { x: last.x + (skewX ? move.x : 0), y: last.y + (skewY ? move.y : 0) })
|
|
137
141
|
skewX ? skewX = -rotation : skewY = rotation
|
|
@@ -147,6 +151,32 @@ export const EditDataHelper = {
|
|
|
147
151
|
getRotateDirection(direction: number, rotation: number, totalDirection = 8): number {
|
|
148
152
|
direction = (direction + Math.round(rotation / (360 / totalDirection))) % totalDirection
|
|
149
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
|
+
|
|
150
180
|
return direction
|
|
151
181
|
}
|
|
152
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
|
}
|
package/src/svg.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const filterStyle = `
|
|
2
|
+
<feOffset dy="1"/>
|
|
3
|
+
<feGaussianBlur stdDeviation="1.5"/>
|
|
4
|
+
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
|
|
5
|
+
<feBlend mode="normal" in="SourceGraphic" result="shape"/>`
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export const resizeSVG = `
|
|
9
|
+
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
|
10
|
+
<g filter="url(#f)">
|
|
11
|
+
<g transform="rotate({{rotation}},12,12)">
|
|
12
|
+
<path d="M7.5 8.0H8.5V5.9L6.8 7.2L7.5 8.0ZM3 11.4L2.3 10.6L1.3 11.4L2.3 12.2L3 11.4ZM7.5 10.4H6.5V11.4H7.5V10.4ZM16.5 10.4V11.4H17.5V10.4H16.5ZM16.5 8.0L17.1 7.2L15.5 5.9V8.0H16.5ZM21 11.4L21.6 12.2L22.6 11.4L21.6 10.6L21 11.4ZM16.5 14.9H15.5V16.9L17.1 15.7L16.5 14.9ZM16.5 12.4H17.5V11.4H16.5V12.4ZM7.5 12.4V11.4H6.5V12.4H7.5ZM7.5 14.9L6.8 15.7L8.5 16.9V14.9H7.5ZM6.8 7.2L2.3 10.6L3.6 12.2L8.1 8.7L6.8 7.2ZM8.5 10.4V8.0H6.5V10.4H8.5ZM16.5 9.4H7.5V11.4H16.5V9.4ZM17.5 10.4V8.0H15.5V10.4H17.5ZM15.8 8.7L20.3 12.2L21.6 10.6L17.1 7.2L15.8 8.7ZM20.3 10.6L15.8 14.1L17.1 15.7L21.6 12.2L20.3 10.6ZM17.5 14.9V12.4H15.5V14.9H17.5ZM7.5 13.4H16.5V11.4H7.5V13.4ZM8.5 14.9V12.4H6.5V14.9H8.5ZM2.3 12.2L6.8 15.7L8.1 14.1L3.6 10.6L2.3 12.2Z" fill="white"/>
|
|
13
|
+
<path fill-rule="evenodd" d="M3 11.4L7.5 8.0V10.4H16.5V8.0L21 11.4L16.5 14.9V12.4H7.5V14.9L3 11.4Z" fill="black"/>
|
|
14
|
+
</g>
|
|
15
|
+
</g>
|
|
16
|
+
<defs>
|
|
17
|
+
<filter id="f" x="-1.6" y="3.9" width="27.2" height="16.9" filterUnits="userSpaceOnUse">
|
|
18
|
+
${filterStyle}
|
|
19
|
+
</filter>
|
|
20
|
+
</defs>
|
|
21
|
+
</svg>
|
|
22
|
+
`
|
|
23
|
+
|
|
24
|
+
export const rotateSVG = `
|
|
25
|
+
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
|
26
|
+
<g filter="url(#f)">
|
|
27
|
+
<g transform="rotate(135,12,12),rotate({{rotation}},12,12)">
|
|
28
|
+
<path d="M20.4 8H21.4L20.8 7.1L17.3 2.6L17 2.1L16.6 2.6L13.1 7.1L12.5 8H13.5H15.4C14.9 11.8 11.8 14.9 8 15.4V13.5V12.5L7.1 13.1L2.6 16.6L2.1 17L2.6 17.3L7.1 20.8L8 21.4V20.4V18.4C13.5 17.9 17.9 13.5 18.4 8H20.4Z" stroke="white"/>
|
|
29
|
+
<path fill-rule="evenodd" d="M17 3L20.4 7.5H17.9C17.7 13.1 13.1 17.7 7.5 17.9V20.4L3 17L7.5 13.5V15.9C12.0 15.7 15.7 12.0 15.9 7.5H13.5L17 3Z" fill="black"/>
|
|
30
|
+
</g>
|
|
31
|
+
</g>
|
|
32
|
+
<defs>
|
|
33
|
+
<filter id="f" x="-1.6" y="-0.6" width="27.1" height="27.1" filterUnits="userSpaceOnUse">
|
|
34
|
+
${filterStyle}
|
|
35
|
+
</filter>
|
|
36
|
+
</defs>
|
|
37
|
+
</svg>
|
|
38
|
+
`
|
|
39
|
+
|
|
40
|
+
export const skewSVG = `
|
|
41
|
+
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
|
42
|
+
<g filter="url(#f)">
|
|
43
|
+
<g transform="rotate(90,12,12),rotate({{rotation}},12,12)">
|
|
44
|
+
<path d="M21 10.4L21 11.4L23.8 11.4L21.6 9.6L21 10.4ZM17 10.4V11.4L17 11.4L17 10.4ZM15.5 6L16.1 5.2L14.5 3.9V6H15.5ZM15.5 8.4V9.4H16.5V8.4H15.5ZM6 8.4V7.4H5V8.4H6ZM6 10.4H5V11.4H6V10.4ZM7 14.4V13.4L7 13.4L7 14.4ZM3 14.4L3 13.4L0.1 13.4L2.3 15.2L3 14.4ZM8.5 18.9L7.8 19.7L9.5 21.0V18.9H8.5ZM8.5 16.4V15.4H7.5V16.4H8.5ZM19 16.4V17.4H20V16.4H19ZM19 14.4H20V13.4H19V14.4ZM21 9.4L17 9.4L17 11.4L21 11.4L21 9.4ZM14.8 6.7L20.3 11.2L21.6 9.6L16.1 5.2L14.8 6.7ZM16.5 8.4V6H14.5V8.4H16.5ZM6 9.4H15.5V7.4H6V9.4ZM7 10.4V8.4H5V10.4H7ZM15.5 9.4H6V11.4H15.5V9.4ZM17 9.4H15.5V11.4H17V9.4ZM7 15.4H8.5V13.4H7V15.4ZM3 15.4L7 15.4L7 13.4L3 13.4L3 15.4ZM9.1 18.1L3.6 13.6L2.3 15.2L7.8 19.7L9.1 18.1ZM7.5 16.4V18.9H9.5V16.4H7.5ZM19 15.4H8.5V17.4H19V15.4ZM18 14.4V16.4H20V14.4H18ZM8.5 15.4H19V13.4H8.5V15.4Z" fill="white"/>
|
|
45
|
+
<path fill-rule="evenodd" d="M17 10.4L21 10.4L15.5 6V8.4H6V10.4H15.5H17ZM8.5 14.4H7L3 14.4L8.5 18.9V16.4H19V14.4H8.5Z" fill="black"/>
|
|
46
|
+
</g>
|
|
47
|
+
</g>
|
|
48
|
+
<defs>
|
|
49
|
+
<filter x="-2.8" y="1.9" width="29.6" height="23.1" filterUnits="userSpaceOnUse" >
|
|
50
|
+
${filterStyle}
|
|
51
|
+
</filter>
|
|
52
|
+
</defs>
|
|
53
|
+
</svg>
|
|
54
|
+
`
|