@leafer-in/editor 1.0.0-rc.8 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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
+ }
@@ -1,78 +1,134 @@
1
- import { IDirection8, IEditor, IEditorScaleEvent, ILine, IEditorSkewEvent } from '@leafer-in/interface'
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'
2
4
 
3
5
  import { EditTool } from './EditTool'
6
+ import { registerEditTool } from './EditToolCreator'
4
7
 
5
8
 
6
- const { left, right } = IDirection8
9
+ const { left, right } = Direction9
10
+ const { move, copy } = PointHelper
7
11
 
12
+ @registerEditTool()
8
13
  export class LineEditTool extends EditTool {
9
14
 
10
- public tag = 'LineEditTool'
15
+ public get tag() { return 'LineEditTool' }
11
16
 
12
17
  public scaleOfEvent = true
13
18
 
14
19
  onScaleWithDrag(e: IEditorScaleEvent): void {
15
20
  const { drag, direction, lockRatio, around } = e
16
- const target = e.target as ILine
21
+ const line = e.target as ILine
22
+ const isDragFrom = direction === left
17
23
 
18
- const fromPoint = { x: 0, y: 0 }
19
- const { toPoint } = target
24
+ if (line.pathInputed) {
20
25
 
21
- target.rotation = 0
26
+ const { path } = line.__
27
+ const { from, to } = this.getFromToByPath(path)
22
28
 
23
- let { x, y } = drag.getInnerMove(target)
29
+ this.dragPoint(from, to, isDragFrom, around, this.getInnerMove(line, drag, lockRatio))
24
30
 
25
- if (lockRatio) {
26
- if (Math.abs(x) > Math.abs(y)) {
27
- y = 0
28
- } else {
29
- x = 0
30
- }
31
- }
31
+ path[1] = from.x, path[2] = from.y
32
+ path[4] = to.x, path[5] = to.y
33
+ line.path = path
32
34
 
33
- if (direction === left) {
35
+ } else if (line.points) {
34
36
 
35
- fromPoint.x += x
36
- fromPoint.y += y
37
+ const { points } = line
38
+ const { from, to } = this.getFromToByPoints(points)
37
39
 
38
- if (around) {
39
- toPoint.x -= x
40
- toPoint.y -= y
41
- }
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
42
45
 
43
46
  } else {
44
47
 
45
- if (around) {
46
- fromPoint.x -= x
47
- fromPoint.y -= y
48
- }
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
+ }
49
63
 
50
- toPoint.x += x
51
- toPoint.y += y
64
+ }
52
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
+ }
53
74
  }
75
+ return movePoint
76
+ }
54
77
 
55
- target.getLocalPointByInner(fromPoint, null, null, true)
56
- target.getLocalPointByInner(toPoint, null, null, true)
57
- target.x = fromPoint.x
58
- target.y = fromPoint.y
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
+ }
59
84
 
60
- target.getInnerPointByLocal(toPoint, null, null, true)
61
- target.toPoint = toPoint
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
+ }
62
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
+ }
63
102
  }
64
103
 
65
104
  onSkew(_e: IEditorSkewEvent): void {
66
105
 
67
106
  }
68
107
 
69
- update(editor: IEditor) {
70
- const { rotatePoints, resizeLines, resizePoints } = editor.editBox
71
- super.update(editor)
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
+ }
72
126
 
73
127
  for (let i = 0; i < 8; i++) {
74
128
  if (i < 4) resizeLines[i].visible = false
75
- resizePoints[i].visible = rotatePoints[i].visible = (i === left || i === right)
129
+ leftOrRight = i === left || i === right
130
+ resizePoints[i].visible = leftOrRight
131
+ rotatePoints[i].visible = fromTo ? false : leftOrRight
76
132
  }
77
133
  }
78
134