@leafer-in/editor 1.0.0-rc.3 → 1.0.0-rc.30

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.
Files changed (41) hide show
  1. package/dist/editor.cjs +1937 -0
  2. package/dist/editor.esm.js +1822 -422
  3. package/dist/editor.esm.min.js +1 -1
  4. package/dist/editor.js +1848 -428
  5. package/dist/editor.min.cjs +1 -0
  6. package/dist/editor.min.js +1 -1
  7. package/package.json +12 -9
  8. package/src/Editor.ts +396 -145
  9. package/src/config.ts +38 -0
  10. package/src/decorator/data.ts +16 -0
  11. package/src/display/EditBox.ts +342 -0
  12. package/src/display/EditMask.ts +37 -0
  13. package/src/display/EditPoint.ts +9 -0
  14. package/src/display/EditSelect.ts +255 -0
  15. package/src/display/SelectArea.ts +30 -0
  16. package/src/display/Stroker.ts +92 -0
  17. package/src/editor/cursor.ts +45 -0
  18. package/src/editor/simulate.ts +14 -0
  19. package/src/editor/target.ts +39 -0
  20. package/src/event/EditorEvent.ts +33 -0
  21. package/src/event/EditorGroupEvent.ts +23 -0
  22. package/src/event/EditorMoveEvent.ts +17 -0
  23. package/src/event/EditorRotateEvent.ts +4 -10
  24. package/src/event/EditorScaleEvent.ts +28 -0
  25. package/src/event/EditorSkewEvent.ts +18 -0
  26. package/src/event/InnerEditorEvent.ts +23 -0
  27. package/src/helper/EditDataHelper.ts +183 -0
  28. package/src/helper/EditSelectHelper.ts +34 -0
  29. package/src/helper/EditorHelper.ts +73 -0
  30. package/src/index.ts +50 -3
  31. package/src/svg.ts +54 -0
  32. package/src/tool/EditTool.ts +99 -0
  33. package/src/tool/EditToolCreator.ts +32 -0
  34. package/src/tool/InnerEditor.ts +68 -0
  35. package/src/tool/LineEditTool.ts +135 -0
  36. package/types/index.d.ts +293 -45
  37. package/src/cursor.ts +0 -57
  38. package/src/event/EditorResizeEvent.ts +0 -34
  39. package/src/resize.ts +0 -87
  40. package/src/tool/LineTool.ts +0 -88
  41. package/src/tool/RectTool.ts +0 -139
package/src/index.ts CHANGED
@@ -1,5 +1,52 @@
1
+ export * from '@leafer-in/resize'
2
+
1
3
  export { Editor } from './Editor'
2
- export { EditorResizeEvent } from './event/EditorResizeEvent'
4
+
5
+ export { EditBox } from './display/EditBox'
6
+ export { EditPoint } from './display/EditPoint'
7
+ export { EditSelect } from './display/EditSelect'
8
+ export { SelectArea } from './display/SelectArea'
9
+ export { Stroker } from './display/Stroker'
10
+
11
+
12
+ export { EditorEvent } from './event/EditorEvent'
13
+ export { EditorMoveEvent } from './event/EditorMoveEvent'
14
+ export { EditorScaleEvent } from './event/EditorScaleEvent'
3
15
  export { EditorRotateEvent } from './event/EditorRotateEvent'
4
- export { LineTool } from './tool/LineTool'
5
- export { RectTool } from './tool/RectTool'
16
+ export { EditorSkewEvent } from './event/EditorSkewEvent'
17
+ export { EditorGroupEvent } from './event/EditorGroupEvent'
18
+ export { InnerEditorEvent } from './event/InnerEditorEvent'
19
+
20
+ export { EditToolCreator, registerEditTool, registerInnerEditor } from './tool/EditToolCreator'
21
+ export { InnerEditor } from './tool/InnerEditor'
22
+ export { EditTool } from './tool/EditTool'
23
+ export { LineEditTool } from './tool/LineEditTool'
24
+
25
+ export { EditorHelper } from './helper/EditorHelper'
26
+ export { EditDataHelper } from './helper/EditDataHelper'
27
+ export { EditSelectHelper } from './helper/EditSelectHelper'
28
+
29
+ import { IEditor, IEditorConfig, IEditToolFunction, IEditorConfigFunction } from '@leafer-in/interface'
30
+ import { Creator, UI, defineKey } from '@leafer-ui/draw'
31
+
32
+ import { Editor } from './Editor'
33
+
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
+ })
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
+ `
@@ -0,0 +1,99 @@
1
+ import { IEditorScaleEvent, IEditorRotateEvent, IEditTool, IEditorSkewEvent, IEditorMoveEvent } from '@leafer-in/interface'
2
+
3
+ import { registerEditTool, EditToolCreator } from './EditToolCreator'
4
+ import { InnerEditor } from './InnerEditor'
5
+
6
+
7
+ @registerEditTool()
8
+ export class EditTool extends InnerEditor implements IEditTool {
9
+
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 {
21
+ const { moveX, moveY, editor } = e
22
+ const { app, list } = editor
23
+ app.lockLayout()
24
+ list.forEach(target => {
25
+ target.moveWorld(moveX, moveY)
26
+ })
27
+ app.unlockLayout()
28
+ }
29
+
30
+ public onScale(e: IEditorScaleEvent): void {
31
+ const { scaleX, scaleY, transform, worldOrigin, editor } = e
32
+ const { app, list } = editor
33
+ app.lockLayout()
34
+ list.forEach(target => {
35
+ const resize = editor.getEditSize(target) !== 'scale'
36
+ if (transform) {
37
+ target.transformWorld(transform, resize)
38
+ } else {
39
+ target.scaleOfWorld(worldOrigin, scaleX, scaleY, resize)
40
+ }
41
+ })
42
+ app.unlockLayout()
43
+ }
44
+
45
+ public onRotate(e: IEditorRotateEvent): void {
46
+ const { rotation, transform, worldOrigin, editor } = e
47
+ const { app, list } = editor
48
+ app.lockLayout()
49
+ list.forEach(target => {
50
+ const resize = editor.getEditSize(target) !== 'scale'
51
+ if (transform) {
52
+ target.transformWorld(transform, resize)
53
+ } else {
54
+ target.rotateOfWorld(worldOrigin, rotation)
55
+ }
56
+ })
57
+ app.unlockLayout()
58
+ }
59
+
60
+ public onSkew(e: IEditorSkewEvent): void {
61
+ const { skewX, skewY, transform, worldOrigin, editor } = e
62
+ const { app, list } = editor
63
+ app.lockLayout()
64
+ list.forEach(target => {
65
+ const resize = editor.getEditSize(target) !== 'scale'
66
+ if (transform) {
67
+ target.transformWorld(transform, resize)
68
+ } else {
69
+ target.skewOfWorld(worldOrigin, skewX, skewY, resize)
70
+ }
71
+ })
72
+ app.unlockLayout()
73
+ }
74
+
75
+ // 状态
76
+
77
+ public load(): void {
78
+ this.editBox.view.visible = true
79
+ this.onLoad()
80
+ }
81
+
82
+ public update(): void {
83
+ const { editor, editBox } = this
84
+
85
+ const { simulateTarget, element } = editor
86
+ if (editor.multiple) simulateTarget.parent.updateLayout()
87
+
88
+ const { x, y, scaleX, scaleY, rotation, skewX, skewY, width, height } = element.getLayoutBounds('box', editor, true)
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()
97
+ }
98
+
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
+ }
@@ -0,0 +1,135 @@
1
+ import { IEditorScaleEvent, ILine, IEditorSkewEvent, IPointData, IAround, IPathCommandData, IFromToData, IUI, IDragEvent } from '@leafer-in/interface'
2
+
3
+ import { getPointData, Direction9, PointHelper } from '@leafer-ui/draw'
4
+
5
+ import { EditTool } from './EditTool'
6
+ import { registerEditTool } from './EditToolCreator'
7
+
8
+
9
+ const { left, right } = Direction9
10
+ const { move, copy } = PointHelper
11
+
12
+ @registerEditTool()
13
+ export class LineEditTool extends EditTool {
14
+
15
+ public get tag() { return 'LineEditTool' }
16
+
17
+ public scaleOfEvent = true
18
+
19
+ onScaleWithDrag(e: IEditorScaleEvent): void {
20
+ const { drag, direction, lockRatio, around } = e
21
+ const line = e.target as ILine
22
+ const isDragFrom = direction === left
23
+
24
+ if (line.pathInputed) {
25
+
26
+ const { path } = line.__
27
+ const { from, to } = this.getFromToByPath(path)
28
+
29
+ this.dragPoint(from, to, isDragFrom, around, this.getInnerMove(line, drag, lockRatio))
30
+
31
+ path[1] = from.x, path[2] = from.y
32
+ path[4] = to.x, path[5] = to.y
33
+ line.path = path
34
+
35
+ } else if (line.points) {
36
+
37
+ const { points } = line
38
+ const { from, to } = this.getFromToByPoints(points)
39
+
40
+ this.dragPoint(from, to, isDragFrom, around, this.getInnerMove(line, drag, lockRatio))
41
+
42
+ points[0] = from.x, points[1] = from.y
43
+ points[2] = to.x, points[3] = to.y
44
+ line.points = points
45
+
46
+ } else {
47
+
48
+ const from = getPointData()
49
+ const { toPoint } = line
50
+ line.rotation = 0
51
+
52
+ this.dragPoint(from, toPoint, isDragFrom, around, this.getInnerMove(line, drag, lockRatio))
53
+
54
+ line.getLocalPointByInner(from, null, null, true)
55
+ line.getLocalPointByInner(toPoint, null, null, true)
56
+ line.x = from.x
57
+ line.y = from.y
58
+
59
+ line.getInnerPointByLocal(toPoint, null, null, true)
60
+ line.toPoint = toPoint
61
+
62
+ }
63
+
64
+ }
65
+
66
+ getInnerMove(ui: IUI, event: IDragEvent, lockRatio: boolean | 'corner'): IPointData {
67
+ const movePoint = event.getInnerMove(ui)
68
+ if (lockRatio) {
69
+ if (Math.abs(movePoint.x) > Math.abs(movePoint.y)) {
70
+ movePoint.y = 0
71
+ } else {
72
+ movePoint.x = 0
73
+ }
74
+ }
75
+ return movePoint
76
+ }
77
+
78
+ getFromToByPath(path: IPathCommandData): IFromToData {
79
+ return {
80
+ from: { x: path[1], y: path[2] },
81
+ to: { x: path[4], y: path[5] }
82
+ }
83
+ }
84
+
85
+ getFromToByPoints(points: number[]): IFromToData {
86
+ return {
87
+ from: { x: points[0], y: points[1] },
88
+ to: { x: points[2], y: points[3] }
89
+ }
90
+
91
+ }
92
+
93
+ dragPoint(fromPoint: IPointData, toPoint: IPointData, isDragFrom: boolean, around: IAround, movePoint: IPointData): void {
94
+ const { x, y } = movePoint
95
+ if (isDragFrom) {
96
+ move(fromPoint, x, y)
97
+ if (around) move(toPoint, -x, -y)
98
+ } else {
99
+ if (around) move(fromPoint, -x, -y)
100
+ move(toPoint, x, y)
101
+ }
102
+ }
103
+
104
+ onSkew(_e: IEditorSkewEvent): void {
105
+
106
+ }
107
+
108
+ onUpdate() {
109
+ const { editBox } = this, { rotatePoints, resizeLines, resizePoints, rect } = editBox
110
+ const line = this.editor.element as ILine
111
+
112
+ let fromTo: IFromToData, leftOrRight: boolean
113
+ if (line.pathInputed) fromTo = this.getFromToByPath(line.__.path)
114
+ else if (line.points) fromTo = this.getFromToByPoints(line.__.points)
115
+
116
+ if (fromTo) {
117
+ const { from, to } = fromTo
118
+ line.innerToWorld(from, from, false, editBox)
119
+ line.innerToWorld(to, to, false, editBox)
120
+ rect.pen.clearPath().moveTo(from.x, from.y).lineTo(to.x, to.y)
121
+ copy(resizePoints[7] as IPointData, from)
122
+ copy(rotatePoints[7] as IPointData, from)
123
+ copy(resizePoints[3] as IPointData, to)
124
+ copy(rotatePoints[3] as IPointData, to)
125
+ }
126
+
127
+ for (let i = 0; i < 8; i++) {
128
+ if (i < 4) resizeLines[i].visible = false
129
+ leftOrRight = i === left || i === right
130
+ resizePoints[i].visible = leftOrRight
131
+ rotatePoints[i].visible = fromTo ? false : leftOrRight
132
+ }
133
+ }
134
+
135
+ }