@leafer-in/editor 1.0.0-rc.9 → 1.0.1

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,128 +1,173 @@
1
- import { IBoundsData, IPointData, IAround } from '@leafer-ui/interface'
2
- import { AroundHelper, PointHelper } from '@leafer-ui/core'
1
+ import { IBoundsData, IPointData, IAround, IAlign, IUI, ILayoutBoundsData } from '@leafer-ui/interface'
2
+ import { AroundHelper, MathHelper, 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
+ const { within } = MathHelper
9
10
 
10
11
  export const EditDataHelper = {
11
12
 
12
- getScaleData(bounds: IBoundsData, direction: IDirection8, pointMove: IPointData, lockRatio: boolean, around: IAround): IEditorScaleEvent {
13
- let origin: IPointData, scaleX: number = 1, scaleY: number = 1
14
- const { width, height } = bounds
13
+ getScaleData(element: IUI, startBounds: ILayoutBoundsData, direction: Direction9, totalMove: IPointData, lockRatio: boolean | 'corner', around: IAround, flipable: boolean, scaleMode: boolean): IEditorScaleEvent {
14
+ let align: IAlign, origin = {} as IPointData, scaleX: number = 1, scaleY: number = 1
15
+
16
+ const { boxBounds, widthRange, heightRange } = element
17
+ const { width, height } = startBounds
15
18
 
16
19
  if (around) {
17
- pointMove.x *= 2
18
- pointMove.y *= 2
20
+ totalMove.x *= 2
21
+ totalMove.y *= 2
19
22
  }
20
23
 
24
+
25
+ // 获取已经改变的比例
26
+ const originChangedScaleX = element.scaleX / startBounds.scaleX
27
+ const originChangedScaleY = element.scaleY / startBounds.scaleY
28
+ const signX = originChangedScaleX < 0 ? -1 : 1
29
+ const signY = originChangedScaleY < 0 ? -1 : 1
30
+
31
+ const changedScaleX = scaleMode ? originChangedScaleX : signX * boxBounds.width / width
32
+ const changedScaleY = scaleMode ? originChangedScaleY : signY * boxBounds.height / height
33
+
34
+ totalMove.x *= scaleMode ? originChangedScaleX : signX
35
+ totalMove.y *= scaleMode ? originChangedScaleY : signY
36
+
37
+
21
38
  // 防止变为0
22
- if (Math.abs(pointMove.x) === width) pointMove.x += 0.1
23
- if (Math.abs(pointMove.y) === height) pointMove.y += 0.1
39
+ if (Math.abs(totalMove.x) === width) totalMove.x += 0.1
40
+ if (Math.abs(totalMove.y) === height) totalMove.y += 0.1
41
+
24
42
 
25
- const topScale = (-pointMove.y + height) / height
26
- const rightScale = (pointMove.x + width) / width
27
- const bottomScale = (pointMove.y + height) / height
28
- const leftScale = (-pointMove.x + width) / width
43
+ const topScale = (-totalMove.y + height) / height
44
+ const rightScale = (totalMove.x + width) / width
45
+ const bottomScale = (totalMove.y + height) / height
46
+ const leftScale = (-totalMove.x + width) / width
29
47
 
30
48
  switch (direction) {
31
49
  case top:
32
50
  scaleY = topScale
33
- origin = { x: 0.5, y: 1 }
51
+ align = 'bottom'
34
52
  break
35
53
  case right:
36
54
  scaleX = rightScale
37
- origin = { x: 0, y: 0.5 }
55
+ align = 'left'
38
56
  break
39
57
  case bottom:
40
58
  scaleY = bottomScale
41
- origin = { x: 0.5, y: 0 }
59
+ align = 'top'
42
60
  break
43
61
  case left:
44
62
  scaleX = leftScale
45
- origin = { x: 1, y: 0.5 }
63
+ align = 'right'
46
64
  break
47
65
  case topLeft:
48
66
  scaleY = topScale
49
67
  scaleX = leftScale
50
- origin = { x: 1, y: 1 }
68
+ align = 'bottom-right'
51
69
  break
52
70
  case topRight:
53
71
  scaleY = topScale
54
72
  scaleX = rightScale
55
- origin = { x: 0, y: 1 }
73
+ align = 'bottom-left'
56
74
  break
57
75
  case bottomRight:
58
76
  scaleY = bottomScale
59
77
  scaleX = rightScale
60
- origin = { x: 0, y: 0 }
78
+ align = 'top-left'
61
79
  break
62
80
  case bottomLeft:
63
81
  scaleY = bottomScale
64
82
  scaleX = leftScale
65
- origin = { x: 1, y: 0 }
83
+ align = 'top-right'
66
84
  }
67
85
 
68
86
  if (lockRatio) {
69
- if (scaleX !== 1) scaleY = scaleX
70
- else scaleX = scaleY
87
+ const unlockSide = lockRatio === 'corner' && direction % 2
88
+ if (!unlockSide) {
89
+ const scale = Math.sqrt(Math.abs(scaleX * scaleY))
90
+ scaleX = scaleX < 0 ? -scale : scale
91
+ scaleY = scaleY < 0 ? -scale : scale
92
+ }
71
93
  }
72
94
 
73
- toPoint(around || origin, bounds, origin)
95
+
96
+ scaleX /= changedScaleX
97
+ scaleY /= changedScaleY
98
+
99
+
100
+ if (!flipable) {
101
+ const { worldTransform } = element
102
+ if (scaleX < 0) scaleX = 1 / boxBounds.width / worldTransform.scaleX
103
+ if (scaleY < 0) scaleY = 1 / boxBounds.height / worldTransform.scaleY
104
+ }
105
+
106
+
107
+ if (widthRange) {
108
+ const nowWidth = boxBounds.width * element.scaleX
109
+ scaleX = within(nowWidth * scaleX, widthRange) / nowWidth
110
+ }
111
+
112
+ if (heightRange) {
113
+ const nowHeight = boxBounds.height * element.scaleY
114
+ scaleY = within(nowHeight * scaleY, heightRange) / nowHeight
115
+ }
116
+
117
+
118
+ toPoint(around || align, boxBounds, origin)
74
119
 
75
120
  return { origin, scaleX, scaleY, direction, lockRatio, around }
76
121
  },
77
122
 
78
- getRotateData(bounds: IBoundsData, direction: IDirection8, current: IPointData, last: IPointData, around: IAround): IEditorRotateEvent {
79
- let origin: IPointData
123
+ getRotateData(bounds: IBoundsData, direction: Direction9, current: IPointData, last: IPointData, around: IAround): IEditorRotateEvent {
124
+ let align: IAlign, origin = {} as IPointData
80
125
 
81
126
  switch (direction) {
82
127
  case topLeft:
83
- origin = { x: 1, y: 1 }
128
+ align = 'bottom-right'
84
129
  break
85
130
  case topRight:
86
- origin = { x: 0, y: 1 }
131
+ align = 'bottom-left'
87
132
  break
88
133
  case bottomRight:
89
- origin = { x: 0, y: 0 }
134
+ align = 'top-left'
90
135
  break
91
136
  case bottomLeft:
92
- origin = { x: 1, y: 0 }
137
+ align = 'top-right'
93
138
  break
94
139
  default:
95
- origin = { x: 0.5, y: 0.5 }
140
+ align = 'center'
96
141
  }
97
142
 
98
- toPoint(around || origin, bounds, origin)
143
+ toPoint(around || align, bounds, origin)
99
144
 
100
145
  return { origin, rotation: PointHelper.getRotation(last, origin, current) }
101
146
  },
102
147
 
103
- getSkewData(bounds: IBoundsData, direction: IDirection8, move: IPointData, around: IAround): IEditorSkewEvent {
104
- let origin: IPointData, skewX = 0, skewY = 0
148
+ getSkewData(bounds: IBoundsData, direction: Direction9, move: IPointData, around: IAround): IEditorSkewEvent {
149
+ let align: IAlign, origin = {} as IPointData, skewX = 0, skewY = 0
105
150
  let last: IPointData
106
151
 
107
152
  switch (direction) {
108
153
  case top:
109
154
  last = { x: 0.5, y: 0 }
110
- origin = { x: 0.5, y: 1 }
155
+ align = 'bottom'
111
156
  skewX = 1
112
157
  break
113
158
  case bottom:
114
159
  last = { x: 0.5, y: 1 }
115
- origin = { x: 0.5, y: 0 }
160
+ align = 'top'
116
161
  skewX = 1
117
162
  break
118
163
  case left:
119
164
  last = { x: 0, y: 0.5 }
120
- origin = { x: 1, y: 0.5 }
165
+ align = 'right'
121
166
  skewY = 1
122
167
  break
123
168
  case right:
124
169
  last = { x: 1, y: 0.5 }
125
- origin = { x: 0, y: 0.5 }
170
+ align = 'left'
126
171
  skewY = 1
127
172
  }
128
173
 
@@ -131,7 +176,7 @@ export const EditDataHelper = {
131
176
  last.x = x + last.x * width
132
177
  last.y = y + last.y * height
133
178
 
134
- toPoint(around || origin, bounds, origin)
179
+ toPoint(around || align, bounds, origin)
135
180
 
136
181
  const rotation = PointHelper.getRotation(last, origin, { x: last.x + (skewX ? move.x : 0), y: last.y + (skewY ? move.y : 0) })
137
182
  skewX ? skewX = -rotation : skewY = rotation
@@ -147,6 +192,32 @@ export const EditDataHelper = {
147
192
  getRotateDirection(direction: number, rotation: number, totalDirection = 8): number {
148
193
  direction = (direction + Math.round(rotation / (360 / totalDirection))) % totalDirection
149
194
  if (direction < 0) direction += totalDirection
195
+ return direction
196
+ },
197
+
198
+ getFlipDirection(direction: Direction9, flipedX: boolean, flipedY: boolean): Direction9 {
199
+ if (flipedX) {
200
+ switch (direction) {
201
+ case left: direction = right; break
202
+ case topLeft: direction = topRight; break
203
+ case bottomLeft: direction = bottomRight; break
204
+ case right: direction = left; break
205
+ case topRight: direction = topLeft; break
206
+ case bottomRight: direction = bottomLeft; break
207
+ }
208
+ }
209
+
210
+ if (flipedY) {
211
+ switch (direction) {
212
+ case top: direction = bottom; break
213
+ case topLeft: direction = bottomLeft; break
214
+ case topRight: direction = bottomRight; break
215
+ case bottom: direction = top; break
216
+ case bottomLeft: direction = topLeft; break
217
+ case bottomRight: direction = topRight; break
218
+ }
219
+ }
220
+
150
221
  return direction
151
222
  }
152
223
 
@@ -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
+ `
@@ -1,70 +1,99 @@
1
- import { IEditor, IEditorScaleEvent, IEditorRotateEvent, IEditTool, IEditorSkewEvent, IEditorMoveEvent } from '@leafer-in/interface'
1
+ import { IEditorScaleEvent, IEditorRotateEvent, IEditTool, IEditorSkewEvent, IEditorMoveEvent } from '@leafer-in/interface'
2
2
 
3
- export class EditTool implements IEditTool {
3
+ import { registerEditTool, EditToolCreator } from './EditToolCreator'
4
+ import { InnerEditor } from './InnerEditor'
4
5
 
5
- static list: IEditTool[] = []
6
6
 
7
- public tag = 'EditTool'
7
+ @registerEditTool()
8
+ export class EditTool extends InnerEditor implements IEditTool {
8
9
 
9
- onMove(e: IEditorMoveEvent): void {
10
+ static registerEditTool() {
11
+ EditToolCreator.register(this)
12
+ }
13
+
14
+
15
+ public get tag() { return 'EditTool' }
16
+
17
+
18
+ // 操作
19
+
20
+ public onMove(e: IEditorMoveEvent): void {
10
21
  const { moveX, moveY, editor } = e
11
22
  const { app, list } = editor
12
23
  app.lockLayout()
13
24
  list.forEach(target => {
14
- const move = target.getLocalPoint({ x: moveX, y: moveY }, null, true)
15
- target.move(move.x, move.y)
25
+ target.moveWorld(moveX, moveY)
16
26
  })
17
27
  app.unlockLayout()
18
28
  }
19
29
 
20
- onScale(e: IEditorScaleEvent): void {
30
+ public onScale(e: IEditorScaleEvent): void {
21
31
  const { scaleX, scaleY, transform, worldOrigin, editor } = e
22
32
  const { app, list } = editor
23
33
  app.lockLayout()
24
34
  list.forEach(target => {
25
- const resize = editor.getEditSize(target) === 'size'
35
+ const resize = editor.getEditSize(target) !== 'scale'
26
36
  if (transform) {
27
- target.transform(transform, resize)
37
+ target.transformWorld(transform, resize)
28
38
  } else {
29
- target.scaleOf(target.getInnerPoint(worldOrigin), scaleX, scaleY, resize)
39
+ target.scaleOfWorld(worldOrigin, scaleX, scaleY, resize)
30
40
  }
31
41
  })
32
42
  app.unlockLayout()
33
43
  }
34
44
 
35
- onRotate(e: IEditorRotateEvent): void {
36
- const { rotation, worldOrigin, editor } = e
45
+ public onRotate(e: IEditorRotateEvent): void {
46
+ const { rotation, transform, worldOrigin, editor } = e
37
47
  const { app, list } = editor
38
48
  app.lockLayout()
39
49
  list.forEach(target => {
40
- target.rotateOf(target.getInnerPoint(worldOrigin), rotation)
50
+ const resize = editor.getEditSize(target) !== 'scale'
51
+ if (transform) {
52
+ target.transformWorld(transform, resize)
53
+ } else {
54
+ target.rotateOfWorld(worldOrigin, rotation)
55
+ }
41
56
  })
42
57
  app.unlockLayout()
43
58
  }
44
59
 
45
- onSkew(e: IEditorSkewEvent): void {
60
+ public onSkew(e: IEditorSkewEvent): void {
46
61
  const { skewX, skewY, transform, worldOrigin, editor } = e
47
62
  const { app, list } = editor
48
63
  app.lockLayout()
49
64
  list.forEach(target => {
50
- const resize = editor.getEditSize(target) === 'size'
65
+ const resize = editor.getEditSize(target) !== 'scale'
51
66
  if (transform) {
52
- target.transform(transform, resize)
67
+ target.transformWorld(transform, resize)
53
68
  } else {
54
- target.skewOf(target.getInnerPoint(worldOrigin), skewX, skewY, resize)
69
+ target.skewOfWorld(worldOrigin, skewX, skewY, resize)
55
70
  }
56
71
  })
57
72
  app.unlockLayout()
58
73
  }
59
74
 
60
- update(editor: IEditor) {
61
- const { simulateTarget, element } = editor
75
+ // 状态
76
+
77
+ public load(): void {
78
+ this.editBox.view.visible = true
79
+ this.onLoad()
80
+ }
62
81
 
82
+ public update(): void {
83
+ const { editor, editBox } = this
84
+
85
+ const { simulateTarget, element } = editor
63
86
  if (editor.multiple) simulateTarget.parent.updateLayout()
64
87
 
65
88
  const { x, y, scaleX, scaleY, rotation, skewX, skewY, width, height } = element.getLayoutBounds('box', editor, true)
66
- editor.editBox.set({ x, y, scaleX, scaleY, rotation, skewX, skewY })
67
- editor.editBox.update({ x: 0, y: 0, width, height })
89
+ editBox.set({ x, y, scaleX, scaleY, rotation, skewX, skewY })
90
+ editBox.update({ x: 0, y: 0, width, height })
91
+ this.onUpdate()
92
+ }
93
+
94
+ public unload(): void {
95
+ this.editBox.view.visible = false
96
+ this.onUnload()
68
97
  }
69
98
 
70
99
  }
@@ -0,0 +1,32 @@
1
+ import { IObject } from '@leafer-ui/interface'
2
+ import { Debug } from '@leafer-ui/draw'
3
+
4
+ import { IEditTool, IEditor } from '@leafer-in/interface'
5
+
6
+
7
+ const debug = Debug.get('EditToolCreator')
8
+
9
+ export function registerEditTool() {
10
+ return (target: IObject) => {
11
+ EditToolCreator.register(target)
12
+ }
13
+ }
14
+
15
+ export const registerInnerEditor = registerEditTool
16
+
17
+ export const EditToolCreator = {
18
+
19
+ list: {} as IObject,
20
+
21
+ register(EditTool: IObject): void {
22
+ const { tag } = EditTool.prototype as IEditTool
23
+ list[tag] ? debug.repeat(tag) : (list[tag] = EditTool)
24
+ },
25
+
26
+ get(tag: string, editor: IEditor): IEditTool {
27
+ return new list[tag](editor)
28
+ }
29
+
30
+ }
31
+
32
+ const { list } = EditToolCreator
@@ -0,0 +1,68 @@
1
+ import { IGroup, IEventListenerId, IUI, IObject } from '@leafer-ui/interface'
2
+ import { IInnerEditor, IEditor, IEditBox } from '@leafer-in/interface'
3
+
4
+ import { Group } from '@leafer-ui/draw'
5
+ import { EditToolCreator } from './EditToolCreator'
6
+
7
+ export class InnerEditor implements IInnerEditor {
8
+
9
+ static registerInnerEditor() {
10
+ EditToolCreator.register(this)
11
+ }
12
+
13
+
14
+ public get tag() { return 'InnerEditor' }
15
+
16
+ public editTarget: IUI
17
+
18
+ public config: IObject
19
+
20
+ public editor: IEditor
21
+ public get editBox(): IEditBox { return this.editor.editBox }
22
+
23
+ public view: IGroup
24
+
25
+ public eventIds: IEventListenerId[]
26
+
27
+
28
+ constructor(editor: IEditor) {
29
+ this.editor = editor
30
+ this.create()
31
+ }
32
+
33
+
34
+ public onCreate(): void { }
35
+ public create(): void {
36
+ this.view = new Group()
37
+ this.onCreate()
38
+ }
39
+
40
+
41
+ // 状态
42
+
43
+ public onLoad(): void { }
44
+ public load(): void {
45
+ this.editor.selector.hittable = this.editor.app.tree.hitChildren = false
46
+ this.onLoad()
47
+ }
48
+
49
+ public onUpdate(): void { }
50
+ public update(): void { this.onUpdate() }
51
+
52
+ public onUnload(): void { }
53
+ public unload(): void {
54
+ this.editor.selector.hittable = this.editor.app.tree.hitChildren = true
55
+ this.onUnload()
56
+ }
57
+
58
+ public onDestroy(): void { }
59
+ public destroy(): void {
60
+ this.onDestroy()
61
+ if (this.editor) {
62
+ if (this.view) this.view.destroy()
63
+ if (this.eventIds) this.editor.off_(this.eventIds)
64
+ this.editor = this.view = this.eventIds = null
65
+ }
66
+ }
67
+
68
+ }