@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.
@@ -1,5 +1,5 @@
1
1
  import { IUI, ILeaferCanvas, IRenderOptions, IRectInputData } from '@leafer-ui/interface'
2
- import { Paint, UI, MatrixHelper } from '@leafer-ui/core'
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
- const { stroke, strokeWidth } = style
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
- let drewPath: boolean
43
+ const aScaleX = abs(leaf.__world.scaleX), aScaleY = abs(leaf.__world.scaleY)
45
44
 
46
- if (leaf.__.editSize === 'scale') {
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
- canvas.setWorld(matrix, options.matrix)
53
- canvas.beginPath()
54
- this.__.strokeWidth = strokeWidth
47
+ copy(matrix, leaf.__world)
48
+ scale(matrix, 1 / aScaleX, 1 / aScaleY)
55
49
 
56
- const { x, y, width, height } = leaf.__layout.boxBounds
57
- canvas.rect(x * aScaleX, y * aScaleY, width * aScaleX, height * aScaleY)
50
+ canvas.setWorld(matrix, options.matrix)
51
+ canvas.beginPath()
52
+ this.__.strokeWidth = strokeWidth
58
53
 
59
- drewPath = true
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
- leaf.__.__pathForRender ? leaf.__drawRenderPath(canvas) : leaf.__drawPathByBox(canvas)
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, options) : Paint.strokes(stroke, this, canvas, options)
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
 
@@ -1,58 +1,45 @@
1
- import { ICursorType, IUIEvent } from '@leafer-ui/interface'
2
- import { IDirection8, IEditor } from '@leafer-in/interface'
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 { topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left } = IDirection8
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.hasTarget || !editBox.visible) return
13
+ if (!point || !editor.editing || !editBox.visible) return
14
+ if (point.name === 'circle') return // 独立旋转按钮
12
15
 
13
16
  let { rotation } = editBox
14
- let { resizeCursor, rotateCursor, resizeable, rotateable } = editor.config
15
- const { direction, pointType } = point
17
+ const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig
18
+ const { pointType } = point, { flippedX, flippedY } = editBox
16
19
 
17
- editBox.enterPoint = point
18
- const isResizePoint = pointType === 'resize'
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
- if (isResizePoint && rotateable && (e.metaKey || e.ctrlKey || !resizeable)) resizeCursor = rotateCursor
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
- if (editBox.flipped) {
23
- const { flippedX, flippedY } = editBox
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
- const index = EditDataHelper.getRotateDirection(direction, rotation)
30
- point.cursor = isResizePoint ? resizeCursor[index] : rotateCursor[index]
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.config.moveCursor
39
+ editor.editBox.rect.cursor = editor.mergeConfig.moveCursor
35
40
  }
36
41
 
37
42
 
38
- export function mirrorCursors(mirror: ICursorType[], mirrorX: boolean, mirrorY: boolean): void {
39
- if (mirrorX) {
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
  }
@@ -1,5 +1,5 @@
1
1
  import { IGroup, ILeaf } from '@leafer-ui/interface'
2
- import { Bounds } from '@leafer-ui/core'
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
  }
@@ -1,4 +1,4 @@
1
- import { LeafList } from '@leafer-ui/core'
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.hasTarget) {
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,9 +1,13 @@
1
1
  import { IUI, IPointData } from '@leafer-ui/interface'
2
- import { Event } from '@leafer-ui/core'
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 { IDirection8, IEditorScaleEvent } from '@leafer-in/interface'
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: IDirection8
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/core'
1
+ import { IBoundsData, IPointData, IAround, IAlign } from '@leafer-ui/interface'
2
+ import { AroundHelper, PointHelper, Direction9 } from '@leafer-ui/draw'
3
3
 
4
- import { IEditorScaleEvent, IDirection8, IEditorSkewEvent, IEditorRotateEvent } from '@leafer-in/interface'
4
+ import { IEditorScaleEvent, IEditorSkewEvent, IEditorRotateEvent } from '@leafer-in/interface'
5
5
 
6
6
 
7
- const { topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left } = IDirection8
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: IDirection8, pointMove: IPointData, lockRatio: boolean, around: IAround): IEditorScaleEvent {
13
- let origin: IPointData, scaleX: number = 1, scaleY: number = 1
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
- origin = { x: 0.5, y: 1 }
33
+ align = 'bottom'
34
34
  break
35
35
  case right:
36
36
  scaleX = rightScale
37
- origin = { x: 0, y: 0.5 }
37
+ align = 'left'
38
38
  break
39
39
  case bottom:
40
40
  scaleY = bottomScale
41
- origin = { x: 0.5, y: 0 }
41
+ align = 'top'
42
42
  break
43
43
  case left:
44
44
  scaleX = leftScale
45
- origin = { x: 1, y: 0.5 }
45
+ align = 'right'
46
46
  break
47
47
  case topLeft:
48
48
  scaleY = topScale
49
49
  scaleX = leftScale
50
- origin = { x: 1, y: 1 }
50
+ align = 'bottom-right'
51
51
  break
52
52
  case topRight:
53
53
  scaleY = topScale
54
54
  scaleX = rightScale
55
- origin = { x: 0, y: 1 }
55
+ align = 'bottom-left'
56
56
  break
57
57
  case bottomRight:
58
58
  scaleY = bottomScale
59
59
  scaleX = rightScale
60
- origin = { x: 0, y: 0 }
60
+ align = 'top-left'
61
61
  break
62
62
  case bottomLeft:
63
63
  scaleY = bottomScale
64
64
  scaleX = leftScale
65
- origin = { x: 1, y: 0 }
65
+ align = 'top-right'
66
66
  }
67
67
 
68
68
  if (lockRatio) {
69
- if (scaleX !== 1) scaleY = scaleX
70
- else scaleX = scaleY
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 || origin, bounds, origin)
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: IDirection8, current: IPointData, last: IPointData, around: IAround): IEditorRotateEvent {
79
- let origin: IPointData
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
- origin = { x: 1, y: 1 }
87
+ align = 'bottom-right'
84
88
  break
85
89
  case topRight:
86
- origin = { x: 0, y: 1 }
90
+ align = 'bottom-left'
87
91
  break
88
92
  case bottomRight:
89
- origin = { x: 0, y: 0 }
93
+ align = 'top-left'
90
94
  break
91
95
  case bottomLeft:
92
- origin = { x: 1, y: 0 }
96
+ align = 'top-right'
93
97
  break
94
98
  default:
95
- origin = { x: 0.5, y: 0.5 }
99
+ align = 'center'
96
100
  }
97
101
 
98
- toPoint(around || origin, bounds, origin)
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: IDirection8, move: IPointData, around: IAround): IEditorSkewEvent {
104
- let origin: IPointData, skewX = 0, skewY = 0
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
- origin = { x: 0.5, y: 1 }
114
+ align = 'bottom'
111
115
  skewX = 1
112
116
  break
113
117
  case bottom:
114
118
  last = { x: 0.5, y: 1 }
115
- origin = { x: 0.5, y: 0 }
119
+ align = 'top'
116
120
  skewX = 1
117
121
  break
118
122
  case left:
119
123
  last = { x: 0, y: 0.5 }
120
- origin = { x: 1, y: 0.5 }
124
+ align = 'right'
121
125
  skewY = 1
122
126
  break
123
127
  case right:
124
128
  last = { x: 1, y: 0.5 }
125
- origin = { x: 0, y: 0.5 }
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 || origin, bounds, origin)
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 { AnswerType, IBounds, ILeafList, IUI } from '@leafer-ui/interface'
1
+ import { IBounds, ILeafList, IUI } from '@leafer-ui/interface'
2
+ import { Answer } from '@leafer-ui/draw'
2
3
 
3
- const { No, Yes, NoAndSkip, YesAndSkip } = AnswerType
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): AnswerType {
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/core'
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, group?: IGroup): IGroup {
10
+ group(list: IUI[], element?: IUI, userGroup?: IGroup | IGroupInputData): IGroup {
11
11
  list.sort(reverseOrder)
12
12
  const { app, parent } = list[0]
13
- if (!group) group = new Group()
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 { LineEditTool } from './tool/LineEditTool'
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/core'
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
- return new Editor(options)
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
+ `