@leafer-ui/display 1.0.0-alpha.7 → 1.0.0-bate
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/package.json +7 -7
- package/src/Box.ts +105 -0
- package/src/Canvas.ts +96 -0
- package/src/Ellipse.ts +21 -18
- package/src/Frame.ts +10 -69
- package/src/Group.ts +19 -8
- package/src/Image.ts +37 -5
- package/src/Line.ts +16 -15
- package/src/Path.ts +10 -15
- package/src/Pen.ts +78 -0
- package/src/Polygon.ts +9 -6
- package/src/Rect.ts +7 -7
- package/src/Star.ts +12 -9
- package/src/Text.ts +109 -34
- package/src/UI.ts +76 -44
- package/src/index.ts +12 -3
- package/src/Vector.ts +0 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafer-ui/display",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-bate",
|
|
4
4
|
"description": "@leafer-ui/display",
|
|
5
5
|
"author": "Chao (Leafer) Wan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
"leaferjs"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@leafer/core": "1.0.0-
|
|
23
|
-
"@leafer-ui/data": "1.0.0-
|
|
24
|
-
"@leafer-ui/display-module": "1.0.0-
|
|
25
|
-
"@leafer-ui/decorator": "1.0.0-
|
|
22
|
+
"@leafer/core": "1.0.0-bate",
|
|
23
|
+
"@leafer-ui/data": "1.0.0-bate",
|
|
24
|
+
"@leafer-ui/display-module": "1.0.0-bate",
|
|
25
|
+
"@leafer-ui/decorator": "1.0.0-bate"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@leafer/interface": "1.0.0-
|
|
29
|
-
"@leafer-ui/interface": "1.0.0-
|
|
28
|
+
"@leafer/interface": "1.0.0-bate",
|
|
29
|
+
"@leafer-ui/interface": "1.0.0-bate"
|
|
30
30
|
}
|
|
31
31
|
}
|
package/src/Box.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { ILeaferCanvas, IRenderOptions, IPathDrawer, IBoundsData, IPathCommandData, __Boolean } from '@leafer/interface'
|
|
2
|
+
import { rewrite, rewriteAble, registerUI, BoundsHelper, dataProcessor, affectRenderBoundsType } from '@leafer/core'
|
|
3
|
+
|
|
4
|
+
import { IBox, IBoxData, IBoxInputData, IOverflow } from '@leafer-ui/interface'
|
|
5
|
+
|
|
6
|
+
import { Group } from './Group'
|
|
7
|
+
import { Rect } from './Rect'
|
|
8
|
+
import { BoxData } from '@leafer-ui/data'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const rect = Rect.prototype
|
|
12
|
+
const group = Group.prototype
|
|
13
|
+
const bounds = {} as IBoundsData
|
|
14
|
+
const { copy, add } = BoundsHelper
|
|
15
|
+
|
|
16
|
+
@rewriteAble()
|
|
17
|
+
@registerUI()
|
|
18
|
+
export class Box extends Group implements IBox {
|
|
19
|
+
|
|
20
|
+
public get __tag() { return 'Box' }
|
|
21
|
+
|
|
22
|
+
@dataProcessor(BoxData)
|
|
23
|
+
public __: IBoxData
|
|
24
|
+
|
|
25
|
+
@affectRenderBoundsType('show')
|
|
26
|
+
public overflow: IOverflow
|
|
27
|
+
|
|
28
|
+
constructor(data?: IBoxInputData) {
|
|
29
|
+
super(data)
|
|
30
|
+
this.isBranchLeaf = true
|
|
31
|
+
this.__layout.renderChanged || this.__layout.renderChange()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@rewrite(rect.__updateStrokeSpread)
|
|
35
|
+
public __updateStrokeSpread(): number { return 0 }
|
|
36
|
+
|
|
37
|
+
@rewrite(rect.__updateRenderSpread)
|
|
38
|
+
public __updateRectRenderSpread(): number { return 0 }
|
|
39
|
+
|
|
40
|
+
public __updateRenderSpread(): number {
|
|
41
|
+
let width = this.__updateRectRenderSpread() || super.__updateRenderSpread()
|
|
42
|
+
this.__.__drawAfterFill = this.__.overflow === 'hide'
|
|
43
|
+
if (!width) width = this.__.__drawAfterFill ? 0 : 1
|
|
44
|
+
return width
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@rewrite(rect.__updateBoxBounds)
|
|
49
|
+
public __updateBoxBounds(): void { }
|
|
50
|
+
|
|
51
|
+
@rewrite(rect.__updateStrokeBounds)
|
|
52
|
+
public __updateStrokeBounds(): void { }
|
|
53
|
+
|
|
54
|
+
public __updateRenderBounds(): void {
|
|
55
|
+
this.__updateRectRenderBounds()
|
|
56
|
+
if (!this.__.__drawAfterFill) {
|
|
57
|
+
const { renderBounds } = this.__layout
|
|
58
|
+
copy(bounds, renderBounds)
|
|
59
|
+
super.__updateRenderBounds()
|
|
60
|
+
add(renderBounds, bounds)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@rewrite(rect.__updateRenderBounds)
|
|
66
|
+
public __updateRectRenderBounds(): void { }
|
|
67
|
+
|
|
68
|
+
@rewrite(rect.__updateChange)
|
|
69
|
+
public __updateRectChange(): void { }
|
|
70
|
+
|
|
71
|
+
public __updateChange(): void {
|
|
72
|
+
super.__updateChange()
|
|
73
|
+
this.__updateRectChange()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@rewrite(rect.__drawPathByData)
|
|
78
|
+
public __drawPathByData(_drawer: IPathDrawer, _data: IPathCommandData): void { }
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@rewrite(rect.__render)
|
|
82
|
+
public __renderRect(_canvas: ILeaferCanvas, _options: IRenderOptions): void { }
|
|
83
|
+
|
|
84
|
+
@rewrite(group.__render)
|
|
85
|
+
public __renderGroup(_canvas: ILeaferCanvas, _options: IRenderOptions): void { }
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
public __render(canvas: ILeaferCanvas, options: IRenderOptions): void {
|
|
89
|
+
if (this.__.__drawAfterFill) {
|
|
90
|
+
this.__renderRect(canvas, options)
|
|
91
|
+
} else {
|
|
92
|
+
this.__renderRect(canvas, options)
|
|
93
|
+
this.__renderGroup(canvas, options)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public __drawAfterFill(canvas: ILeaferCanvas, options: IRenderOptions): void {
|
|
98
|
+
canvas.save()
|
|
99
|
+
canvas.clip()
|
|
100
|
+
this.__renderGroup(canvas, options)
|
|
101
|
+
canvas.restore()
|
|
102
|
+
if (this.__.stroke) this.__drawRenderPath(canvas)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
}
|
package/src/Canvas.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { ILeaferCanvas, ILeaferCanvasConfig, __String, __Number, IRenderOptions, IPointData, ICanvasContext2D, IScreenSizeData, ISizeData, IHitType } from '@leafer/interface'
|
|
2
|
+
import { Creator, Matrix, Platform, dataProcessor, registerUI, hitType } from '@leafer/core'
|
|
3
|
+
|
|
4
|
+
import { ICanvas, ICanvasData, ICanvasInputData, IUI } from '@leafer-ui/interface'
|
|
5
|
+
import { ImageData } from '@leafer-ui/data'
|
|
6
|
+
|
|
7
|
+
import { Rect } from './Rect'
|
|
8
|
+
import { resizeType } from '@leafer-ui/decorator'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@registerUI()
|
|
12
|
+
export class Canvas extends Rect implements ICanvas {
|
|
13
|
+
|
|
14
|
+
public get __tag() { return 'Canvas' }
|
|
15
|
+
|
|
16
|
+
@dataProcessor(ImageData)
|
|
17
|
+
public __: ICanvasData
|
|
18
|
+
|
|
19
|
+
@resizeType(100)
|
|
20
|
+
public width: __Number
|
|
21
|
+
|
|
22
|
+
@resizeType(100)
|
|
23
|
+
public height: __Number
|
|
24
|
+
|
|
25
|
+
@resizeType(Platform.devicePixelRatio)
|
|
26
|
+
public pixelRatio: __Number
|
|
27
|
+
|
|
28
|
+
@resizeType(true)
|
|
29
|
+
public smooth: boolean
|
|
30
|
+
|
|
31
|
+
@hitType('all')
|
|
32
|
+
public hitFill: IHitType
|
|
33
|
+
|
|
34
|
+
public canvas: ILeaferCanvas
|
|
35
|
+
|
|
36
|
+
public context: ICanvasContext2D
|
|
37
|
+
|
|
38
|
+
constructor(data?: ICanvasInputData) {
|
|
39
|
+
super(data)
|
|
40
|
+
this.canvas = Creator.canvas(this.__ as ILeaferCanvasConfig)
|
|
41
|
+
this.context = this.canvas.context
|
|
42
|
+
this.__.__drawAfterFill = true
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public draw(ui: IUI, offset?: IPointData, scale?: number | IPointData, rotation?: number): void {
|
|
46
|
+
ui.__layout.checkUpdate()
|
|
47
|
+
|
|
48
|
+
const matrix = new Matrix(ui.__world)
|
|
49
|
+
matrix.invert()
|
|
50
|
+
|
|
51
|
+
const m = new Matrix()
|
|
52
|
+
if (offset) m.translate(offset.x, offset.y)
|
|
53
|
+
if (scale) typeof scale === 'number' ? m.scale(scale) : m.scale(scale.x, scale.y)
|
|
54
|
+
if (rotation) m.rotate(rotation)
|
|
55
|
+
matrix.preMultiply(m)
|
|
56
|
+
|
|
57
|
+
ui.__render(this.canvas, { matrix })
|
|
58
|
+
this.paint()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public paint(): void {
|
|
62
|
+
this.forceUpdate('fill')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public __drawAfterFill(canvas: ILeaferCanvas, _options: IRenderOptions): void {
|
|
66
|
+
const origin = this.canvas.view as ISizeData
|
|
67
|
+
const { width, height } = this
|
|
68
|
+
if (this.__.cornerRadius) {
|
|
69
|
+
canvas.save()
|
|
70
|
+
canvas.clip()
|
|
71
|
+
canvas.drawImage(this.canvas.view as any, 0, 0, origin.width, origin.height, 0, 0, width, height)
|
|
72
|
+
canvas.restore()
|
|
73
|
+
} else {
|
|
74
|
+
canvas.drawImage(this.canvas.view as any, 0, 0, origin.width, origin.height, 0, 0, width, height)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public __updateSize(): void {
|
|
79
|
+
const { canvas } = this
|
|
80
|
+
if (canvas) {
|
|
81
|
+
const { smooth } = this.__
|
|
82
|
+
if (canvas.smooth !== smooth) canvas.smooth = smooth
|
|
83
|
+
canvas.resize(this.__ as IScreenSizeData)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public destroy(): void {
|
|
88
|
+
if (this.canvas) {
|
|
89
|
+
this.canvas.destroy()
|
|
90
|
+
this.canvas = null
|
|
91
|
+
this.context = null
|
|
92
|
+
}
|
|
93
|
+
super.destroy()
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
}
|
package/src/Ellipse.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __Number } from '@leafer/interface'
|
|
2
|
+
import { PathCommandDataHelper, dataProcessor, pathType, registerUI } from '@leafer/core'
|
|
2
3
|
|
|
3
4
|
import { IEllipse, IEllipseInputData, IEllipseData } from '@leafer-ui/interface'
|
|
4
5
|
import { EllipseData } from '@leafer-ui/data'
|
|
@@ -6,24 +7,24 @@ import { EllipseData } from '@leafer-ui/data'
|
|
|
6
7
|
import { UI } from './UI'
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
const {
|
|
10
|
-
const { begin, moveTo, close, ellipse } = PathCreator
|
|
11
|
-
|
|
10
|
+
const { moveTo, closePath, ellipse } = PathCommandDataHelper
|
|
12
11
|
|
|
13
12
|
@registerUI()
|
|
14
13
|
export class Ellipse extends UI implements IEllipse {
|
|
15
14
|
|
|
15
|
+
public get __tag() { return 'Ellipse' }
|
|
16
|
+
|
|
16
17
|
@dataProcessor(EllipseData)
|
|
17
18
|
public __: IEllipseData
|
|
18
19
|
|
|
19
20
|
@pathType(0)
|
|
20
|
-
public innerRadius:
|
|
21
|
+
public innerRadius: __Number
|
|
21
22
|
|
|
22
23
|
@pathType(0)
|
|
23
|
-
public startAngle:
|
|
24
|
+
public startAngle: __Number
|
|
24
25
|
|
|
25
26
|
@pathType(0)
|
|
26
|
-
public endAngle:
|
|
27
|
+
public endAngle: __Number
|
|
27
28
|
|
|
28
29
|
constructor(data?: IEllipseInputData) {
|
|
29
30
|
super(data)
|
|
@@ -34,28 +35,30 @@ export class Ellipse extends UI implements IEllipse {
|
|
|
34
35
|
const { width, height, innerRadius, startAngle, endAngle } = this.__
|
|
35
36
|
const rx = width / 2, ry = height / 2
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
const path: number[] = this.__.path = []
|
|
38
39
|
|
|
39
40
|
if (innerRadius) {
|
|
40
41
|
|
|
41
42
|
if (startAngle || endAngle) {
|
|
42
|
-
ellipse(rx, ry, rx *
|
|
43
|
-
ellipse(rx, ry, rx, ry, 0, endAngle
|
|
44
|
-
|
|
43
|
+
if (innerRadius < 1) ellipse(path, rx, ry, rx * innerRadius, ry * innerRadius, 0, startAngle, endAngle, false)
|
|
44
|
+
ellipse(path, rx, ry, rx, ry, 0, endAngle, startAngle, true)
|
|
45
|
+
if (innerRadius < 1) closePath(path)
|
|
45
46
|
} else {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
if (innerRadius < 1) {
|
|
48
|
+
ellipse(path, rx, ry, rx * innerRadius, ry * innerRadius)
|
|
49
|
+
moveTo(path, width, ry)
|
|
50
|
+
}
|
|
51
|
+
ellipse(path, rx, ry, rx, ry, 0, 0, 360, true)
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
} else {
|
|
52
55
|
|
|
53
56
|
if (startAngle || endAngle) {
|
|
54
|
-
moveTo(rx, ry)
|
|
55
|
-
ellipse(rx, ry, rx, ry, 0, startAngle
|
|
56
|
-
|
|
57
|
+
moveTo(path, rx, ry)
|
|
58
|
+
ellipse(path, rx, ry, rx, ry, 0, startAngle, endAngle, false)
|
|
59
|
+
closePath(path)
|
|
57
60
|
} else {
|
|
58
|
-
ellipse(rx, ry, rx, ry
|
|
61
|
+
ellipse(path, rx, ry, rx, ry)
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
}
|
package/src/Frame.ts
CHANGED
|
@@ -1,84 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { __Boolean } from '@leafer/interface'
|
|
2
|
+
import { dataProcessor, registerUI, affectRenderBoundsType } from '@leafer/core'
|
|
3
3
|
|
|
4
|
-
import { IFrame, IFrameData, IFrameInputData } from '@leafer-ui/interface'
|
|
4
|
+
import { IFrame, IFrameData, IFrameInputData, IOverflow } from '@leafer-ui/interface'
|
|
5
5
|
import { FrameData } from '@leafer-ui/data'
|
|
6
|
-
import { FrameRender } from '@leafer-ui/display-module'
|
|
7
6
|
|
|
8
|
-
import {
|
|
9
|
-
import { Rect } from './Rect'
|
|
7
|
+
import { Box } from './Box'
|
|
10
8
|
|
|
11
9
|
|
|
12
|
-
const rect = Rect.prototype
|
|
13
|
-
const group = Group.prototype
|
|
14
|
-
const bounds = {} as IBoundsData
|
|
15
|
-
const { copy, add } = BoundsHelper
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@useModule(FrameRender)
|
|
19
|
-
@rewriteAble()
|
|
20
10
|
@registerUI()
|
|
21
|
-
export class Frame extends
|
|
11
|
+
export class Frame extends Box implements IFrame {
|
|
12
|
+
|
|
13
|
+
public get __tag() { return 'Frame' }
|
|
22
14
|
|
|
23
15
|
@dataProcessor(FrameData)
|
|
24
16
|
public __: IFrameData
|
|
25
17
|
|
|
26
|
-
@
|
|
27
|
-
public
|
|
18
|
+
@affectRenderBoundsType('hide')
|
|
19
|
+
public overflow: IOverflow
|
|
28
20
|
|
|
29
21
|
constructor(data?: IFrameInputData) {
|
|
30
22
|
super(data)
|
|
31
|
-
if (!this.fill) this.fill = '#FFFFFF'
|
|
32
|
-
this.__isBranchLeaf = true
|
|
23
|
+
if (!this.__.fill) this.__.fill = '#FFFFFF'
|
|
33
24
|
}
|
|
34
|
-
|
|
35
|
-
@rewrite(rect.__drawPathByData)
|
|
36
|
-
public __drawPathByData(_drawer: ICanvasDrawPath, _data: IPathCommandData): void { }
|
|
37
|
-
|
|
38
|
-
public __updateBoxBounds(): void {
|
|
39
|
-
this.__updateRectBoxBounds()
|
|
40
|
-
if (!this.__.clip) {
|
|
41
|
-
const { boxBounds } = this.__layout
|
|
42
|
-
copy(bounds, boxBounds)
|
|
43
|
-
super.__updateBoxBounds()
|
|
44
|
-
add(boxBounds, bounds)
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public __updateEventBounds(): void {
|
|
49
|
-
this.__updateRectEventBounds()
|
|
50
|
-
if (!this.__.clip) {
|
|
51
|
-
const { eventBounds } = this.__layout
|
|
52
|
-
copy(bounds, eventBounds)
|
|
53
|
-
super.__updateEventBounds()
|
|
54
|
-
add(eventBounds, bounds)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
public __updateRenderBounds(): void {
|
|
59
|
-
this.__updateRectRenderBounds()
|
|
60
|
-
if (!this.__.clip) {
|
|
61
|
-
const { renderBounds } = this.__layout
|
|
62
|
-
copy(bounds, renderBounds)
|
|
63
|
-
super.__updateRenderBounds()
|
|
64
|
-
add(renderBounds, bounds)
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
@rewrite(rect.__updateBoxBounds)
|
|
69
|
-
public __updateRectBoxBounds(): void { }
|
|
70
|
-
|
|
71
|
-
@rewrite(rect.__updateEventBounds)
|
|
72
|
-
public __updateRectEventBounds(): void { }
|
|
73
|
-
|
|
74
|
-
@rewrite(rect.__updateRenderBounds)
|
|
75
|
-
public __updateRectRenderBounds(): void { }
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
@rewrite(rect.__render)
|
|
79
|
-
public __renderRect(_canvas: ILeaferCanvas, _options: IRenderOptions): void { }
|
|
80
|
-
|
|
81
|
-
@rewrite(group.__render)
|
|
82
|
-
public __renderGroup(_canvas: ILeaferCanvas, _options: IRenderOptions): void { }
|
|
83
|
-
|
|
84
25
|
}
|
package/src/Group.ts
CHANGED
|
@@ -10,23 +10,30 @@ import { UI } from './UI'
|
|
|
10
10
|
@registerUI()
|
|
11
11
|
export class Group extends UI implements IGroup {
|
|
12
12
|
|
|
13
|
+
public get __tag() { return 'Group' }
|
|
14
|
+
|
|
13
15
|
@dataProcessor(GroupData)
|
|
14
16
|
public __: IGroupData
|
|
15
17
|
|
|
16
18
|
public children: IUI[]
|
|
17
19
|
|
|
20
|
+
public set mask(child: IUI) {
|
|
21
|
+
if (this.__hasMask) this.__removeMask()
|
|
22
|
+
if (child) {
|
|
23
|
+
child.isMask = true
|
|
24
|
+
this.addAt(child, 0)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
public get mask(): IUI {
|
|
28
|
+
return this.children.find(item => item.isMask)
|
|
29
|
+
}
|
|
30
|
+
|
|
18
31
|
constructor(data?: IGroupInputData) {
|
|
19
32
|
super(data)
|
|
20
|
-
this.
|
|
33
|
+
this.isBranch = true
|
|
21
34
|
this.children = []
|
|
22
35
|
}
|
|
23
36
|
|
|
24
|
-
public __updatePath(): void {
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
public add(_child: IUI, _index?: number): void { } // Branch rewrite
|
|
29
|
-
|
|
30
37
|
public addAt(child: IUI, index: number): void {
|
|
31
38
|
this.add(child, index)
|
|
32
39
|
}
|
|
@@ -39,6 +46,10 @@ export class Group extends UI implements IGroup {
|
|
|
39
46
|
this.add(child, this.children.indexOf(before))
|
|
40
47
|
}
|
|
41
48
|
|
|
42
|
-
|
|
49
|
+
// Branch rewrite
|
|
50
|
+
|
|
51
|
+
public add(_child: IUI, _index?: number): void { }
|
|
52
|
+
|
|
53
|
+
public remove(_child?: IUI): void { }
|
|
43
54
|
|
|
44
55
|
}
|
package/src/Image.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ILeaferImage, __String } from '@leafer/interface'
|
|
2
|
+
import { ImageEvent, boundsType, dataProcessor, registerUI } from '@leafer/core'
|
|
2
3
|
|
|
3
|
-
import { IImage, IImageInputData, IImageData } from '@leafer-ui/interface'
|
|
4
|
+
import { IImage, IImageInputData, IImageData, IImagePaint } from '@leafer-ui/interface'
|
|
4
5
|
import { ImageData } from '@leafer-ui/data'
|
|
5
6
|
|
|
6
7
|
import { Rect } from './Rect'
|
|
@@ -9,17 +10,48 @@ import { Rect } from './Rect'
|
|
|
9
10
|
@registerUI()
|
|
10
11
|
export class Image extends Rect implements IImage {
|
|
11
12
|
|
|
13
|
+
public get __tag() { return 'Image' }
|
|
14
|
+
|
|
12
15
|
@dataProcessor(ImageData)
|
|
13
16
|
public __: IImageData
|
|
14
17
|
|
|
15
18
|
@boundsType('')
|
|
16
|
-
public url:
|
|
19
|
+
public url: __String
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
public get ready(): boolean { return this.image ? this.image.ready : false }
|
|
22
|
+
|
|
23
|
+
public image: ILeaferImage
|
|
20
24
|
|
|
21
25
|
constructor(data?: IImageInputData) {
|
|
22
26
|
super(data)
|
|
23
27
|
}
|
|
24
28
|
|
|
29
|
+
public __updateBoxBounds(): void {
|
|
30
|
+
|
|
31
|
+
let update: boolean
|
|
32
|
+
|
|
33
|
+
const { url } = this
|
|
34
|
+
const fill = this.fill as IImagePaint
|
|
35
|
+
|
|
36
|
+
if (fill) {
|
|
37
|
+
if (fill.url !== url) update = true
|
|
38
|
+
} else {
|
|
39
|
+
if (url) update = true
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (update) {
|
|
43
|
+
if (this.image) this.image = null
|
|
44
|
+
this.fill = { type: 'image', mode: 'strench', url }
|
|
45
|
+
this.once(ImageEvent.LOADED, (e) => this.image = e.image)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
super.__updateBoxBounds()
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public destroy(): void {
|
|
53
|
+
this.image = null
|
|
54
|
+
super.destroy()
|
|
55
|
+
}
|
|
56
|
+
|
|
25
57
|
}
|
package/src/Line.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { IPointData, ITwoPointBoundsData, __Number } from '@leafer/interface'
|
|
2
|
+
import { PathCommandDataHelper, PointHelper, TwoPointBoundsHelper, boundsType, affectStrokeBoundsType, dataProcessor, registerUI } from '@leafer/core'
|
|
3
3
|
|
|
4
|
-
import { ILine, ILineData, ILineInputData } from '@leafer-ui/interface'
|
|
4
|
+
import { ILine, ILineData, ILineInputData, IStrokeAlign } from '@leafer-ui/interface'
|
|
5
5
|
import { LineData } from '@leafer-ui/data'
|
|
6
6
|
|
|
7
7
|
import { UI } from './UI'
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
const {
|
|
10
|
+
const { moveTo, lineTo } = PathCommandDataHelper
|
|
11
11
|
const { rotate, getAngle, getDistance, defaultPoint } = PointHelper
|
|
12
12
|
const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper
|
|
13
13
|
|
|
@@ -17,26 +17,28 @@ const pointBounds = {} as ITwoPointBoundsData
|
|
|
17
17
|
@registerUI()
|
|
18
18
|
export class Line extends UI implements ILine {
|
|
19
19
|
|
|
20
|
+
public get __tag() { return 'Line' }
|
|
21
|
+
|
|
20
22
|
@dataProcessor(LineData)
|
|
21
23
|
public __: ILineData
|
|
22
24
|
|
|
23
25
|
@boundsType()
|
|
24
26
|
public rotation: __Number
|
|
25
27
|
|
|
28
|
+
@affectStrokeBoundsType('center')
|
|
29
|
+
public strokeAlign: IStrokeAlign
|
|
26
30
|
|
|
27
|
-
protected
|
|
31
|
+
protected __toPoint: IPointData
|
|
28
32
|
|
|
29
33
|
public get toPoint(): IPointData {
|
|
30
|
-
if (this.
|
|
34
|
+
if (this.__toPoint && !this.__layout.boxChanged) return this.__toPoint
|
|
31
35
|
|
|
32
|
-
const { width,
|
|
36
|
+
const { width, rotation } = this.__
|
|
33
37
|
const to: IPointData = { x: 0, y: 0 }
|
|
34
38
|
|
|
35
39
|
if (width) to.x = width
|
|
36
|
-
if (height) to.y = height
|
|
37
|
-
|
|
38
40
|
if (rotation) rotate(to, rotation)
|
|
39
|
-
this.
|
|
41
|
+
this.__toPoint = to
|
|
40
42
|
|
|
41
43
|
return to
|
|
42
44
|
}
|
|
@@ -54,17 +56,16 @@ export class Line extends UI implements ILine {
|
|
|
54
56
|
|
|
55
57
|
public __updatePath(): void {
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
moveTo(0, 0)
|
|
59
|
+
const path: number[] = this.__.path = []
|
|
60
|
+
moveTo(path, 0, 0)
|
|
59
61
|
|
|
60
62
|
const to = this.toPoint
|
|
61
|
-
lineTo(to.x, to.y)
|
|
62
|
-
end()
|
|
63
|
+
lineTo(path, to.x, to.y)
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
public __updateBoxBounds(): void {
|
|
66
67
|
setPoint(pointBounds, 0, 0)
|
|
67
|
-
addPoint(pointBounds, this.
|
|
68
|
+
addPoint(pointBounds, this.__toPoint.x, this.__toPoint.y)
|
|
68
69
|
toBounds(pointBounds, this.__layout.boxBounds)
|
|
69
70
|
}
|
|
70
71
|
|
package/src/Path.ts
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { IPathCommandData, IWindingRule } from '@leafer/interface'
|
|
2
|
+
import { PathBounds, dataProcessor, pathType, affectStrokeBoundsType, registerUI } from '@leafer/core'
|
|
3
3
|
|
|
4
|
-
import { IPath, IPathData, IPathInputData,
|
|
4
|
+
import { IPath, IPathData, IPathInputData, IPathString, IStrokeAlign } from '@leafer-ui/interface'
|
|
5
5
|
import { PathData } from '@leafer-ui/data'
|
|
6
6
|
|
|
7
7
|
import { UI } from './UI'
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
const {
|
|
11
|
-
const { toBounds } = TwoPointBoundsHelper
|
|
12
|
-
|
|
13
|
-
const pointBounds = {} as ITwoPointBoundsData
|
|
14
|
-
|
|
10
|
+
const { toBounds } = PathBounds
|
|
15
11
|
|
|
16
12
|
@registerUI()
|
|
17
13
|
export class Path extends UI implements IPath {
|
|
18
14
|
|
|
15
|
+
public get __tag() { return 'Path' }
|
|
16
|
+
|
|
19
17
|
@dataProcessor(PathData)
|
|
20
18
|
public __: IPathData
|
|
21
19
|
|
|
@@ -25,18 +23,15 @@ export class Path extends UI implements IPath {
|
|
|
25
23
|
@pathType()
|
|
26
24
|
public windingRule: IWindingRule
|
|
27
25
|
|
|
26
|
+
@affectStrokeBoundsType('center')
|
|
27
|
+
public strokeAlign: IStrokeAlign
|
|
28
|
+
|
|
28
29
|
constructor(data?: IPathInputData) {
|
|
29
30
|
super(data)
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
public __drawRenderPath(canvas: ILeaferCanvas): void {
|
|
33
|
-
canvas.beginPath()
|
|
34
|
-
this.__drawPathByData(canvas, this.__.path)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
33
|
public __updateBoxBounds(): void {
|
|
38
|
-
|
|
39
|
-
toBounds(pointBounds, this.__layout.boxBounds)
|
|
34
|
+
toBounds(this.__.path, this.__layout.boxBounds)
|
|
40
35
|
}
|
|
41
36
|
|
|
42
37
|
}
|
package/src/Pen.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { PathCreator, dataProcessor, registerUI, useModule } from '@leafer/core'
|
|
2
|
+
|
|
3
|
+
import { IPenData, IPenInputData, IPathInputData, IPathCommandData, IPath } from '@leafer-ui/interface'
|
|
4
|
+
import { PenData } from '@leafer-ui/data'
|
|
5
|
+
|
|
6
|
+
import { Group } from './Group'
|
|
7
|
+
import { Path } from './Path'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@useModule(PathCreator, ['beginPath'])
|
|
11
|
+
@registerUI()
|
|
12
|
+
export class Pen extends Group {
|
|
13
|
+
|
|
14
|
+
public get __tag() { return 'Pen' }
|
|
15
|
+
|
|
16
|
+
@dataProcessor(PenData)
|
|
17
|
+
public __: IPenData
|
|
18
|
+
|
|
19
|
+
public pathElement: IPath
|
|
20
|
+
public pathStyle: IPathInputData
|
|
21
|
+
public path: IPathCommandData
|
|
22
|
+
|
|
23
|
+
constructor(data?: IPenInputData) {
|
|
24
|
+
super(data)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public setStyle(data: IPathInputData): Pen {
|
|
28
|
+
const path = this.pathElement = new Path(data)
|
|
29
|
+
this.pathStyle = data
|
|
30
|
+
this.path = path.path as IPathCommandData || (path.path = [])
|
|
31
|
+
this.add(path)
|
|
32
|
+
return this
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public beginPath(): Pen {
|
|
36
|
+
this.path.length = 0
|
|
37
|
+
this.paint()
|
|
38
|
+
return this
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// svg and canvas
|
|
42
|
+
|
|
43
|
+
public moveTo(_x: number, _y: number): Pen { return this }
|
|
44
|
+
|
|
45
|
+
public lineTo(_x: number, _y: number): Pen { return this }
|
|
46
|
+
|
|
47
|
+
public bezierCurveTo(_x1: number, _y1: number, _x2: number, _y2: number, _x: number, _y: number): Pen { return this }
|
|
48
|
+
|
|
49
|
+
public quadraticCurveTo(_x1: number, _y1: number, _x: number, _y: number): Pen { return this }
|
|
50
|
+
|
|
51
|
+
public closePath(): Pen { return this }
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
// canvas
|
|
55
|
+
|
|
56
|
+
public rect(_x: number, _y: number, _width: number, _height: number): Pen { return this }
|
|
57
|
+
|
|
58
|
+
public roundRect(_x: number, _y: number, _width: number, _height: number, _cornerRadius: number | number[]): Pen { return this }
|
|
59
|
+
|
|
60
|
+
public ellipse(_x: number, _y: number, _radiusX: number, _radiusY: number, _rotation?: number, _startAngle?: number, _endAngle?: number, _anticlockwise?: boolean): Pen { return this }
|
|
61
|
+
|
|
62
|
+
public arc(_x: number, _y: number, _radius: number, _startAngle?: number, _endAngle?: number, _anticlockwise?: boolean): Pen { return this }
|
|
63
|
+
|
|
64
|
+
public arcTo(_x1: number, _y1: number, _x2: number, _y2: number, _radius: number): Pen { return this }
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
// moveTo, then draw
|
|
68
|
+
|
|
69
|
+
public moveToEllipse(_x: number, _y: number, _radiusX: number, _radiusY: number, _rotation?: number, _startAngle?: number, _endAngle?: number, _anticlockwise?: boolean): Pen { return this }
|
|
70
|
+
|
|
71
|
+
public moveToArc(_x: number, _y: number, _radius: number, _startAngle?: number, _endAngle?: number, _anticlockwise?: boolean): Pen { return this }
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
public paint(): void {
|
|
75
|
+
this.pathElement.forceUpdate('path')
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
}
|
package/src/Polygon.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __Number } from '@leafer/interface'
|
|
2
|
+
import { PathCommandDataHelper, dataProcessor, pathType, registerUI } from '@leafer/core'
|
|
2
3
|
|
|
3
4
|
import { IPolygon, IPolygonData, IPolygonInputData } from '@leafer-ui/interface'
|
|
4
5
|
import { PolygonData } from '@leafer-ui/data'
|
|
@@ -7,12 +8,14 @@ import { UI } from './UI'
|
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
const { sin, cos, PI } = Math
|
|
10
|
-
const {
|
|
11
|
+
const { moveTo, lineTo, closePath } = PathCommandDataHelper
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
@registerUI()
|
|
14
15
|
export class Polygon extends UI implements IPolygon {
|
|
15
16
|
|
|
17
|
+
public get __tag() { return 'Polygon' }
|
|
18
|
+
|
|
16
19
|
@dataProcessor(PolygonData)
|
|
17
20
|
public __: IPolygonData
|
|
18
21
|
|
|
@@ -28,14 +31,14 @@ export class Polygon extends UI implements IPolygon {
|
|
|
28
31
|
const { width, height, sides } = this.__
|
|
29
32
|
const rx = width / 2, ry = height / 2
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
moveTo(rx, 0)
|
|
34
|
+
const path: number[] = this.__.path = []
|
|
35
|
+
moveTo(path, rx, 0)
|
|
33
36
|
|
|
34
37
|
for (let i = 1; i < sides; i++) {
|
|
35
|
-
lineTo(rx + rx * sin((i * 2 * PI) / sides), ry - ry * cos((i * 2 * PI) / sides))
|
|
38
|
+
lineTo(path, rx + rx * sin((i * 2 * PI) / sides), ry - ry * cos((i * 2 * PI) / sides))
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
closePath(path)
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
}
|
package/src/Rect.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IPathDrawer, IPathCommandData, __Number } from '@leafer/interface'
|
|
2
2
|
import { dataProcessor, registerUI, useModule } from '@leafer/core'
|
|
3
3
|
|
|
4
4
|
import { IRect, IRectInputData, IRectData } from '@leafer-ui/interface'
|
|
@@ -12,6 +12,8 @@ import { UI } from './UI'
|
|
|
12
12
|
@registerUI()
|
|
13
13
|
export class Rect extends UI implements IRect {
|
|
14
14
|
|
|
15
|
+
public get __tag() { return 'Rect' }
|
|
16
|
+
|
|
15
17
|
@dataProcessor(RectData)
|
|
16
18
|
public __: IRectData
|
|
17
19
|
|
|
@@ -19,12 +21,10 @@ export class Rect extends UI implements IRect {
|
|
|
19
21
|
super(data)
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
public
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (borderRadius) {
|
|
27
|
-
drawer.roundRect(0, 0, width, height, borderRadius)
|
|
24
|
+
public __drawPathByData(drawer: IPathDrawer, _data: IPathCommandData): void {
|
|
25
|
+
const { width, height, cornerRadius } = this.__
|
|
26
|
+
if (cornerRadius) {
|
|
27
|
+
drawer.roundRect(0, 0, width, height, cornerRadius)
|
|
28
28
|
} else {
|
|
29
29
|
drawer.rect(0, 0, width, height)
|
|
30
30
|
}
|
package/src/Star.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __Number } from '@leafer/interface'
|
|
2
|
+
import { PathCommandDataHelper, dataProcessor, pathType, registerUI } from '@leafer/core'
|
|
2
3
|
|
|
3
4
|
import { IStar, IStarData, IStarInputData } from '@leafer-ui/interface'
|
|
4
5
|
import { StarData } from '@leafer-ui/data'
|
|
@@ -7,20 +8,22 @@ import { UI } from './UI'
|
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
const { sin, cos, PI } = Math
|
|
10
|
-
const {
|
|
11
|
+
const { moveTo, lineTo, closePath } = PathCommandDataHelper
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
@registerUI()
|
|
14
15
|
export class Star extends UI implements IStar {
|
|
15
16
|
|
|
17
|
+
public get __tag() { return 'Star' }
|
|
18
|
+
|
|
16
19
|
@dataProcessor(StarData)
|
|
17
20
|
public __: IStarData
|
|
18
21
|
|
|
19
22
|
@pathType(5)
|
|
20
|
-
public points:
|
|
23
|
+
public points: __Number
|
|
21
24
|
|
|
22
|
-
@pathType(0.
|
|
23
|
-
public innerRadius:
|
|
25
|
+
@pathType(0.382)
|
|
26
|
+
public innerRadius: __Number
|
|
24
27
|
|
|
25
28
|
constructor(data?: IStarInputData) {
|
|
26
29
|
super(data)
|
|
@@ -31,14 +34,14 @@ export class Star extends UI implements IStar {
|
|
|
31
34
|
const { width, height, points, innerRadius } = this.__
|
|
32
35
|
const rx = width / 2, ry = height / 2
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
moveTo(rx, 0)
|
|
37
|
+
const path: number[] = this.__.path = []
|
|
38
|
+
moveTo(path, rx, 0)
|
|
36
39
|
|
|
37
40
|
for (let i = 1; i < points * 2; i++) {
|
|
38
|
-
lineTo(rx + (i % 2 === 0 ? rx : rx * innerRadius) * sin((i * PI) / points), ry - (i % 2 === 0 ? ry : ry * innerRadius) * cos((i * PI) / points))
|
|
41
|
+
lineTo(path, rx + (i % 2 === 0 ? rx : rx * innerRadius) * sin((i * PI) / points), ry - (i % 2 === 0 ? ry : ry * innerRadius) * cos((i * PI) / points))
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
closePath(path)
|
|
42
45
|
|
|
43
46
|
}
|
|
44
47
|
|
package/src/Text.ts
CHANGED
|
@@ -1,78 +1,153 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ILeaferCanvas, IPathDrawer, IPathCommandData, __Boolean, __Number, __String } from '@leafer/interface'
|
|
2
|
+
import { BoundsHelper, boundsType, dataProcessor, registerUI, affectStrokeBoundsType } from '@leafer/core'
|
|
3
3
|
|
|
4
|
-
import { IText, IFontWeight, ITextCase, ITextDecoration,
|
|
5
|
-
import { TextData } from '@leafer-ui/data'
|
|
6
|
-
import {
|
|
4
|
+
import { IText, IFontWeight, ITextCase, ITextDecoration, ITextData, ITextInputData, ITextAlign, IVerticalAlign, ITextDrawData, IOverflow, IUnitData, IStrokeAlign } from '@leafer-ui/interface'
|
|
5
|
+
import { TextData, UnitConvert } from '@leafer-ui/data'
|
|
6
|
+
import { TextConvert } from '@leafer-ui/text'
|
|
7
7
|
|
|
8
8
|
import { UI } from './UI'
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
const { copyAndSpread, includes, spread } = BoundsHelper
|
|
12
|
+
|
|
12
13
|
@registerUI()
|
|
13
14
|
export class Text extends UI implements IText {
|
|
14
15
|
|
|
16
|
+
public get __tag() { return 'Text' }
|
|
17
|
+
|
|
15
18
|
@dataProcessor(TextData)
|
|
16
19
|
public __: ITextData
|
|
17
20
|
|
|
21
|
+
// size
|
|
22
|
+
@boundsType(0)
|
|
23
|
+
public width: __Number
|
|
24
|
+
|
|
25
|
+
@boundsType(0)
|
|
26
|
+
public height: __Number
|
|
27
|
+
|
|
28
|
+
@boundsType(0)
|
|
29
|
+
public padding: number | number[]
|
|
30
|
+
|
|
31
|
+
@affectStrokeBoundsType('outside')
|
|
32
|
+
public strokeAlign: IStrokeAlign
|
|
33
|
+
|
|
18
34
|
@boundsType('')
|
|
19
|
-
public
|
|
35
|
+
public text: __String
|
|
20
36
|
|
|
21
|
-
@boundsType('
|
|
22
|
-
public fontFamily:
|
|
37
|
+
@boundsType('L')
|
|
38
|
+
public fontFamily: __String
|
|
23
39
|
|
|
24
40
|
@boundsType(12)
|
|
25
|
-
public fontSize:
|
|
41
|
+
public fontSize: __Number
|
|
26
42
|
|
|
27
43
|
@boundsType('normal')
|
|
28
44
|
public fontWeight: IFontWeight
|
|
29
45
|
|
|
30
46
|
@boundsType(false)
|
|
31
|
-
public italic:
|
|
47
|
+
public italic: __Boolean
|
|
32
48
|
|
|
33
|
-
@boundsType('
|
|
49
|
+
@boundsType('none')
|
|
34
50
|
public textCase: ITextCase
|
|
35
51
|
|
|
36
|
-
@boundsType('
|
|
52
|
+
@boundsType('none')
|
|
37
53
|
public textDecoration: ITextDecoration
|
|
38
54
|
|
|
39
|
-
@boundsType()
|
|
40
|
-
public letterSpacing:
|
|
55
|
+
@boundsType(0)
|
|
56
|
+
public letterSpacing: __Number | IUnitData
|
|
57
|
+
|
|
58
|
+
@boundsType({ type: 'percent', value: 150 } as IUnitData)
|
|
59
|
+
public lineHeight: __Number | IUnitData
|
|
60
|
+
|
|
61
|
+
@boundsType(0)
|
|
62
|
+
public paraIndent: __Number
|
|
63
|
+
|
|
64
|
+
@boundsType(0)
|
|
65
|
+
public paraSpacing: __Number
|
|
41
66
|
|
|
42
|
-
@boundsType()
|
|
43
|
-
public
|
|
67
|
+
@boundsType('left')
|
|
68
|
+
public textAlign: ITextAlign
|
|
44
69
|
|
|
45
|
-
@boundsType()
|
|
46
|
-
public
|
|
70
|
+
@boundsType('top')
|
|
71
|
+
public verticalAlign: IVerticalAlign
|
|
47
72
|
|
|
48
|
-
@boundsType()
|
|
49
|
-
public
|
|
73
|
+
@boundsType('show')
|
|
74
|
+
public textOverflow: IOverflow | string
|
|
75
|
+
|
|
76
|
+
public get textDrawData(): ITextDrawData {
|
|
77
|
+
this.__layout.checkUpdate()
|
|
78
|
+
return this.__.__textDrawData
|
|
79
|
+
}
|
|
50
80
|
|
|
51
81
|
constructor(data?: ITextInputData) {
|
|
52
82
|
super(data)
|
|
53
83
|
}
|
|
54
84
|
|
|
55
|
-
public
|
|
85
|
+
public __drawHitPath(canvas: ILeaferCanvas): void {
|
|
86
|
+
const { __lineHeight, __baseLine, __textDrawData: data } = this.__
|
|
87
|
+
canvas.beginPath()
|
|
88
|
+
data.rows.forEach(row => canvas.rect(row.x, row.y - __baseLine, row.width, __lineHeight))
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public __drawPathByData(drawer: IPathDrawer, _data: IPathCommandData): void {
|
|
92
|
+
const { x, y, width, height } = this.__layout.boxBounds
|
|
93
|
+
drawer.rect(x, y, width, height)
|
|
94
|
+
}
|
|
56
95
|
|
|
96
|
+
public __drawRenderPath(canvas: ILeaferCanvas): void {
|
|
97
|
+
canvas.font = this.__.__font
|
|
57
98
|
}
|
|
58
99
|
|
|
59
|
-
public
|
|
60
|
-
const
|
|
61
|
-
|
|
100
|
+
public __updateTextDrawData(): void {
|
|
101
|
+
const data = this.__
|
|
102
|
+
data.__textDrawData = TextConvert.getDrawData(data.text, this.__)
|
|
103
|
+
|
|
62
104
|
}
|
|
63
105
|
|
|
64
106
|
public __updateBoxBounds(): void {
|
|
65
|
-
const { fontFamily, fontSize, fontWeight, italic, textCase, lineHeight } = this.__
|
|
66
|
-
const b = this.__layout.boxBounds
|
|
67
107
|
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
const height =
|
|
108
|
+
const data = this.__
|
|
109
|
+
const layout = this.__layout
|
|
110
|
+
const { width, height, lineHeight, letterSpacing, fontFamily, fontSize, fontWeight, italic, textCase } = data
|
|
111
|
+
|
|
112
|
+
// compute
|
|
113
|
+
|
|
114
|
+
data.__lineHeight = UnitConvert.number(lineHeight, fontSize)
|
|
115
|
+
data.__letterSpacing = UnitConvert.number(letterSpacing, fontSize)
|
|
116
|
+
data.__baseLine = data.__lineHeight - (data.__lineHeight - fontSize * 0.7) / 2
|
|
117
|
+
data.__font = `${italic ? 'italic ' : ''}${textCase === 'small-caps' ? 'small-caps ' : ''}${fontWeight !== 'normal' ? fontWeight + ' ' : ''}${fontSize}px ${fontFamily}`
|
|
118
|
+
|
|
119
|
+
this.__updateTextDrawData()
|
|
120
|
+
|
|
121
|
+
const { bounds } = data.__textDrawData
|
|
122
|
+
const b = layout.boxBounds
|
|
123
|
+
|
|
124
|
+
if (data.__lineHeight < fontSize) spread(bounds, fontSize / 2)
|
|
125
|
+
|
|
126
|
+
if (width && height) {
|
|
127
|
+
super.__updateBoxBounds()
|
|
128
|
+
} else {
|
|
129
|
+
b.x = width ? 0 : bounds.x
|
|
130
|
+
b.y = height ? 0 : bounds.y
|
|
131
|
+
b.width = width ? width : bounds.width
|
|
132
|
+
b.height = height ? height : bounds.height
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const contentBounds = includes(b, bounds) ? b : bounds
|
|
136
|
+
if (contentBounds !== layout.contentBounds) {
|
|
137
|
+
layout.contentBounds = contentBounds
|
|
138
|
+
layout.renderChanged = true
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
public __updateRenderSpread(): number {
|
|
144
|
+
let width = super.__updateRenderSpread()
|
|
145
|
+
if (!width) width = this.__layout.boxBounds === this.__layout.contentBounds ? 0 : 1
|
|
146
|
+
return width
|
|
147
|
+
}
|
|
71
148
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
b.width = width
|
|
75
|
-
b.height = height
|
|
149
|
+
public __updateRenderBounds(): void {
|
|
150
|
+
copyAndSpread(this.__layout.renderBounds, this.__layout.contentBounds, this.__layout.renderSpread)
|
|
76
151
|
}
|
|
77
152
|
|
|
78
153
|
}
|
package/src/UI.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { ILeaferCanvas,
|
|
2
|
-
import { Leaf,
|
|
1
|
+
import { ILeaferCanvas, IPathDrawer, IPathCommandData, IHitType, __Number, __Boolean, __String } from '@leafer/interface'
|
|
2
|
+
import { Leaf, PathDrawer, surfaceType, dataType, positionType, boundsType, pathType, scaleType, rotationType, opacityType, sortType, maskType, dataProcessor, useModule, rewrite, rewriteAble, UICreator, PathCorner, hitType, strokeType, PathConvert } from '@leafer/core'
|
|
3
3
|
|
|
4
|
-
import { IUI, IShadowEffect, IBlurEffect, IPaint, IStrokeAlign, IStrokeJoin, IStrokeCap, IBlendMode, IPaintString, IDashPatternString, IShadowString, IGrayscaleEffect, IUIData, IGroup,
|
|
4
|
+
import { IUI, IShadowEffect, IBlurEffect, IPaint, IStrokeAlign, IStrokeJoin, IStrokeCap, IBlendMode, IPaintString, IDashPatternString, IShadowString, IGrayscaleEffect, IUIData, IGroup, IStrokeWidthString, ICornerRadiusString, IUITagInputData, IUIInputData, IPathString } from '@leafer-ui/interface'
|
|
5
5
|
import { effectType } from '@leafer-ui/decorator'
|
|
6
6
|
|
|
7
7
|
import { UIData } from '@leafer-ui/data'
|
|
8
8
|
import { UIBounds, UIHit, UIRender } from '@leafer-ui/display-module'
|
|
9
9
|
|
|
10
|
+
import { Paint } from '@leafer-ui/external'
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
@useModule(UIBounds)
|
|
12
14
|
@useModule(UIHit)
|
|
@@ -14,11 +16,9 @@ import { UIBounds, UIHit, UIRender } from '@leafer-ui/display-module'
|
|
|
14
16
|
@rewriteAble()
|
|
15
17
|
export class UI extends Leaf implements IUI {
|
|
16
18
|
|
|
17
|
-
|
|
18
19
|
@dataProcessor(UIData)
|
|
19
20
|
public __: IUIData
|
|
20
21
|
|
|
21
|
-
public root?: IGroup
|
|
22
22
|
public parent?: IGroup
|
|
23
23
|
|
|
24
24
|
// ---
|
|
@@ -35,15 +35,24 @@ export class UI extends Leaf implements IUI {
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
// layer
|
|
38
|
+
@surfaceType('pass-through')
|
|
39
|
+
public blendMode: IBlendMode
|
|
40
|
+
|
|
38
41
|
@opacityType(1)
|
|
39
42
|
public opacity: __Number
|
|
40
43
|
|
|
41
44
|
@opacityType(true)
|
|
42
45
|
public visible: __Boolean
|
|
43
46
|
|
|
47
|
+
@maskType(false)
|
|
48
|
+
public isMask: __Boolean
|
|
49
|
+
|
|
44
50
|
@sortType(0)
|
|
45
51
|
public zIndex: __Number
|
|
46
52
|
|
|
53
|
+
@dataType()
|
|
54
|
+
public locked: __Boolean
|
|
55
|
+
|
|
47
56
|
|
|
48
57
|
// position
|
|
49
58
|
@positionType(0)
|
|
@@ -79,67 +88,65 @@ export class UI extends Leaf implements IUI {
|
|
|
79
88
|
@rotationType(0)
|
|
80
89
|
public skewY: __Number
|
|
81
90
|
|
|
91
|
+
|
|
92
|
+
@dataType(false)
|
|
82
93
|
public draggable: __Boolean
|
|
83
94
|
|
|
84
|
-
//
|
|
95
|
+
// hit
|
|
96
|
+
@hitType(true)
|
|
97
|
+
public hittable: __Boolean
|
|
85
98
|
|
|
99
|
+
@hitType('path')
|
|
100
|
+
public hitFill: IHitType
|
|
86
101
|
|
|
87
|
-
|
|
102
|
+
@strokeType('path')
|
|
103
|
+
public hitStroke: IHitType
|
|
88
104
|
|
|
89
|
-
@
|
|
90
|
-
public
|
|
105
|
+
@hitType(true)
|
|
106
|
+
public hitChildren: __Boolean
|
|
91
107
|
|
|
92
|
-
@
|
|
93
|
-
public
|
|
108
|
+
@hitType(true)
|
|
109
|
+
public hitSelf: __Boolean
|
|
110
|
+
|
|
111
|
+
// ---
|
|
94
112
|
|
|
95
|
-
@dataType()
|
|
96
|
-
public locked: __Boolean
|
|
97
113
|
|
|
98
114
|
// fill
|
|
99
115
|
|
|
100
116
|
@surfaceType()
|
|
101
117
|
public fill: IPaint | IPaint[] | IPaintString
|
|
102
118
|
|
|
103
|
-
// border
|
|
104
|
-
|
|
105
|
-
@pathType()
|
|
106
|
-
public borderRadius: __Number | __Number[] | IBorderRadiusString
|
|
107
|
-
|
|
108
|
-
@affectEventBoundsType(1)
|
|
109
|
-
public borderWidth: __Number | __Number[] | IBorderWidthString
|
|
110
|
-
|
|
111
|
-
|
|
112
119
|
// stroke
|
|
113
120
|
|
|
114
|
-
@
|
|
121
|
+
@strokeType()
|
|
115
122
|
public stroke: IPaint | IPaint[] | IPaintString
|
|
116
123
|
|
|
117
|
-
@
|
|
124
|
+
@strokeType('inside')
|
|
118
125
|
public strokeAlign: IStrokeAlign
|
|
119
126
|
|
|
120
|
-
@
|
|
121
|
-
public strokeWidth:
|
|
127
|
+
@strokeType(1)
|
|
128
|
+
public strokeWidth: number | number[] | IStrokeWidthString
|
|
122
129
|
|
|
123
|
-
@
|
|
130
|
+
@strokeType('none')
|
|
124
131
|
public strokeCap: IStrokeCap
|
|
125
132
|
|
|
126
|
-
@
|
|
133
|
+
@strokeType('miter')
|
|
127
134
|
public strokeJoin: IStrokeJoin
|
|
128
135
|
|
|
129
|
-
@
|
|
136
|
+
@strokeType()
|
|
130
137
|
public dashPattern: __Number[] | IDashPatternString
|
|
131
138
|
|
|
132
|
-
@
|
|
139
|
+
@strokeType()
|
|
133
140
|
public dashOffset: __Number
|
|
134
141
|
|
|
135
|
-
@
|
|
142
|
+
@strokeType(10)
|
|
136
143
|
public miterLimit: __Number
|
|
137
144
|
|
|
138
145
|
|
|
139
146
|
// corner
|
|
140
147
|
|
|
141
148
|
@pathType()
|
|
142
|
-
public cornerRadius:
|
|
149
|
+
public cornerRadius: number | number[] | ICornerRadiusString
|
|
143
150
|
|
|
144
151
|
@pathType()
|
|
145
152
|
public cornerSmoothing: __Number
|
|
@@ -162,28 +169,49 @@ export class UI extends Leaf implements IUI {
|
|
|
162
169
|
public grayscale: __Number | IGrayscaleEffect
|
|
163
170
|
|
|
164
171
|
|
|
165
|
-
|
|
172
|
+
constructor(data?: IUIInputData) {
|
|
173
|
+
super(data)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
public set(data: IUITagInputData): void {
|
|
178
|
+
Object.assign(this, data)
|
|
179
|
+
}
|
|
166
180
|
|
|
167
|
-
public get
|
|
181
|
+
public get(): IUITagInputData {
|
|
182
|
+
return this.__.__getInputData()
|
|
183
|
+
}
|
|
168
184
|
|
|
169
|
-
public get relativeTransform(): IMatrixData { return this.__layout.getTransform('relative') }
|
|
170
185
|
|
|
171
|
-
|
|
186
|
+
public getPath(curve?: boolean): IPathCommandData {
|
|
187
|
+
const path = this.__.path
|
|
188
|
+
if (!path) return []
|
|
189
|
+
return curve ? PathConvert.toCanvasData(path, true) : path
|
|
190
|
+
}
|
|
172
191
|
|
|
173
|
-
public
|
|
192
|
+
public getPathString(curve?: boolean): IPathString {
|
|
193
|
+
return PathConvert.stringify(this.getPath(curve))
|
|
194
|
+
}
|
|
174
195
|
|
|
175
|
-
public get worldRenderBounds(): IBoundsData { return this.__layout.getBounds('world', 'render') }
|
|
176
196
|
|
|
197
|
+
public __onUpdateSize(): void {
|
|
198
|
+
if (this.__.__input) {
|
|
199
|
+
const { fill, stroke } = this.__.__input
|
|
200
|
+
if (fill) Paint.computeFill(this)
|
|
201
|
+
if (stroke) Paint.computeStroke(this)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
177
204
|
|
|
178
205
|
public __updateRenderPath(): void {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
206
|
+
if (this.__.path) {
|
|
207
|
+
const { __: data } = this
|
|
208
|
+
data.__pathForRender = data.cornerRadius ? PathCorner.smooth(data.path, data.cornerRadius, data.cornerSmoothing) : data.path
|
|
209
|
+
}
|
|
182
210
|
}
|
|
183
211
|
|
|
184
212
|
public __drawRenderPath(canvas: ILeaferCanvas): void {
|
|
185
213
|
canvas.beginPath()
|
|
186
|
-
this.__drawPathByData(canvas, this.__.
|
|
214
|
+
this.__drawPathByData(canvas, this.__.__pathForRender)
|
|
187
215
|
}
|
|
188
216
|
|
|
189
217
|
public __drawPath(canvas: ILeaferCanvas): void {
|
|
@@ -191,7 +219,11 @@ export class UI extends Leaf implements IUI {
|
|
|
191
219
|
this.__drawPathByData(canvas, this.__.path)
|
|
192
220
|
}
|
|
193
221
|
|
|
194
|
-
@rewrite(
|
|
195
|
-
public __drawPathByData(_drawer:
|
|
222
|
+
@rewrite(PathDrawer.drawPathByData)
|
|
223
|
+
public __drawPathByData(_drawer: IPathDrawer, _data: IPathCommandData): void { }
|
|
224
|
+
|
|
225
|
+
static one(data: IUITagInputData, x?: number, y?: number, width?: number, height?: number): IUI {
|
|
226
|
+
return UICreator.get(data.tag || this.prototype.__tag, data, x, y, width, height) as IUI
|
|
227
|
+
}
|
|
196
228
|
|
|
197
229
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
export { UI } from './UI'
|
|
2
|
+
|
|
2
3
|
export { Group } from './Group'
|
|
4
|
+
export { Box } from './Box'
|
|
3
5
|
export { Frame } from './Frame'
|
|
6
|
+
|
|
4
7
|
export { Rect } from './Rect'
|
|
5
8
|
export { Ellipse } from './Ellipse'
|
|
6
9
|
export { Polygon } from './Polygon'
|
|
7
10
|
export { Star } from './Star'
|
|
8
11
|
export { Line } from './Line'
|
|
9
|
-
|
|
10
|
-
export { Vector } from './Vector'
|
|
11
|
-
export { Text } from './Text'
|
|
12
|
+
|
|
12
13
|
export { Image } from './Image'
|
|
14
|
+
export { Canvas } from './Canvas'
|
|
15
|
+
|
|
16
|
+
export { Text } from './Text'
|
|
17
|
+
|
|
18
|
+
export { Path } from './Path'
|
|
19
|
+
export { Pen } from './Pen'
|
|
20
|
+
|
|
21
|
+
|
|
13
22
|
|
package/src/Vector.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { dataProcessor, pathType, registerUI } from '@leafer/core'
|
|
2
|
-
|
|
3
|
-
import { IVectorPath, IVectorPathString, IVector, IVectorData, IVectorInputData } from '@leafer-ui/interface'
|
|
4
|
-
import { VectorData } from '@leafer-ui/data'
|
|
5
|
-
|
|
6
|
-
import { Group } from './Group'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@registerUI()
|
|
10
|
-
export class Vector extends Group implements IVector {
|
|
11
|
-
|
|
12
|
-
@dataProcessor(VectorData)
|
|
13
|
-
public __: IVectorData
|
|
14
|
-
|
|
15
|
-
@pathType()
|
|
16
|
-
public paths: IVectorPath[] | IVectorPathString
|
|
17
|
-
|
|
18
|
-
constructor(data?: IVectorInputData) {
|
|
19
|
-
super(data)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
public __updatePath(): void {
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
}
|