@leafer-ui/display 1.0.0-alpha.9 → 1.0.0-beta
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 +8 -7
- package/src/Box.ts +105 -0
- package/src/Canvas.ts +96 -0
- package/src/Ellipse.ts +17 -16
- package/src/Frame.ts +10 -69
- package/src/Group.ts +14 -1
- package/src/Image.ts +36 -5
- package/src/Line.ts +12 -8
- package/src/Path.ts +10 -15
- package/src/Pen.ts +78 -0
- package/src/Polygon.ts +8 -6
- package/src/Rect.ts +2 -0
- package/src/Star.ts +9 -7
- package/src/Text.ts +108 -29
- package/src/UI.ts +69 -29
- 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-beta",
|
|
4
4
|
"description": "@leafer-ui/display",
|
|
5
5
|
"author": "Chao (Leafer) Wan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,13 +19,14 @@
|
|
|
19
19
|
"leaferjs"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@leafer/core": "1.0.0-
|
|
23
|
-
"@leafer-ui/data": "1.0.0-
|
|
24
|
-
"@leafer-ui/
|
|
25
|
-
"@leafer-ui/
|
|
22
|
+
"@leafer/core": "1.0.0-beta",
|
|
23
|
+
"@leafer-ui/data": "1.0.0-beta",
|
|
24
|
+
"@leafer-ui/text": "1.0.0-beta",
|
|
25
|
+
"@leafer-ui/display-module": "1.0.0-beta",
|
|
26
|
+
"@leafer-ui/decorator": "1.0.0-beta"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
|
-
"@leafer/interface": "1.0.0-
|
|
29
|
-
"@leafer-ui/interface": "1.0.0-
|
|
29
|
+
"@leafer/interface": "1.0.0-beta",
|
|
30
|
+
"@leafer-ui/interface": "1.0.0-beta"
|
|
30
31
|
}
|
|
31
32
|
}
|
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,5 +1,5 @@
|
|
|
1
1
|
import { __Number } from '@leafer/interface'
|
|
2
|
-
import {
|
|
2
|
+
import { PathCommandDataHelper, dataProcessor, pathType, registerUI } from '@leafer/core'
|
|
3
3
|
|
|
4
4
|
import { IEllipse, IEllipseInputData, IEllipseData } from '@leafer-ui/interface'
|
|
5
5
|
import { EllipseData } from '@leafer-ui/data'
|
|
@@ -7,14 +7,13 @@ import { EllipseData } from '@leafer-ui/data'
|
|
|
7
7
|
import { UI } from './UI'
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
const { PI } = Math
|
|
12
|
-
const { begin, moveTo, close, ellipse } = PathCreator
|
|
13
|
-
|
|
10
|
+
const { moveTo, closePath, ellipse } = PathCommandDataHelper
|
|
14
11
|
|
|
15
12
|
@registerUI()
|
|
16
13
|
export class Ellipse extends UI implements IEllipse {
|
|
17
14
|
|
|
15
|
+
public get __tag() { return 'Ellipse' }
|
|
16
|
+
|
|
18
17
|
@dataProcessor(EllipseData)
|
|
19
18
|
public __: IEllipseData
|
|
20
19
|
|
|
@@ -36,28 +35,30 @@ export class Ellipse extends UI implements IEllipse {
|
|
|
36
35
|
const { width, height, innerRadius, startAngle, endAngle } = this.__
|
|
37
36
|
const rx = width / 2, ry = height / 2
|
|
38
37
|
|
|
39
|
-
|
|
38
|
+
const path: number[] = this.__.path = []
|
|
40
39
|
|
|
41
40
|
if (innerRadius) {
|
|
42
41
|
|
|
43
42
|
if (startAngle || endAngle) {
|
|
44
|
-
ellipse(rx, ry, rx *
|
|
45
|
-
ellipse(rx, ry, rx, ry, 0, endAngle
|
|
46
|
-
|
|
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)
|
|
47
46
|
} else {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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)
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
} else {
|
|
54
55
|
|
|
55
56
|
if (startAngle || endAngle) {
|
|
56
|
-
moveTo(rx, ry)
|
|
57
|
-
ellipse(rx, ry, rx, ry, 0, startAngle
|
|
58
|
-
|
|
57
|
+
moveTo(path, rx, ry)
|
|
58
|
+
ellipse(path, rx, ry, rx, ry, 0, startAngle, endAngle, false)
|
|
59
|
+
closePath(path)
|
|
59
60
|
} else {
|
|
60
|
-
ellipse(rx, ry, rx, ry
|
|
61
|
+
ellipse(path, rx, ry, rx, ry)
|
|
61
62
|
}
|
|
62
63
|
|
|
63
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: IPathDrawer, _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,14 +10,27 @@ 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
|
|
package/src/Image.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { __String } from '@leafer/interface'
|
|
2
|
-
import { boundsType, dataProcessor, registerUI } from '@leafer/core'
|
|
1
|
+
import { ILeaferImage, __String } from '@leafer/interface'
|
|
2
|
+
import { ImageEvent, boundsType, dataProcessor, registerUI } from '@leafer/core'
|
|
3
3
|
|
|
4
|
-
import { IImage, IImageInputData, IImageData } from '@leafer-ui/interface'
|
|
4
|
+
import { IImage, IImageInputData, IImageData, IImagePaint } from '@leafer-ui/interface'
|
|
5
5
|
import { ImageData } from '@leafer-ui/data'
|
|
6
6
|
|
|
7
7
|
import { Rect } from './Rect'
|
|
@@ -10,17 +10,48 @@ import { Rect } from './Rect'
|
|
|
10
10
|
@registerUI()
|
|
11
11
|
export class Image extends Rect implements IImage {
|
|
12
12
|
|
|
13
|
+
public get __tag() { return 'Image' }
|
|
14
|
+
|
|
13
15
|
@dataProcessor(ImageData)
|
|
14
16
|
public __: IImageData
|
|
15
17
|
|
|
16
18
|
@boundsType('')
|
|
17
19
|
public url: __String
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
public get ready(): boolean { return this.image ? this.image.ready : false }
|
|
22
|
+
|
|
23
|
+
public image: ILeaferImage
|
|
21
24
|
|
|
22
25
|
constructor(data?: IImageInputData) {
|
|
23
26
|
super(data)
|
|
24
27
|
}
|
|
25
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
|
+
|
|
26
57
|
}
|
package/src/Line.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { IPointData, ITwoPointBoundsData, __Number } from '@leafer/interface'
|
|
2
|
-
import {
|
|
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,16 +17,21 @@ 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
|
|
30
|
+
|
|
26
31
|
protected __toPoint: IPointData
|
|
27
32
|
|
|
28
33
|
public get toPoint(): IPointData {
|
|
29
|
-
if (this.__toPoint && !this.__layout.
|
|
34
|
+
if (this.__toPoint && !this.__layout.boxChanged) return this.__toPoint
|
|
30
35
|
|
|
31
36
|
const { width, rotation } = this.__
|
|
32
37
|
const to: IPointData = { x: 0, y: 0 }
|
|
@@ -51,12 +56,11 @@ export class Line extends UI implements ILine {
|
|
|
51
56
|
|
|
52
57
|
public __updatePath(): void {
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
moveTo(0, 0)
|
|
59
|
+
const path: number[] = this.__.path = []
|
|
60
|
+
moveTo(path, 0, 0)
|
|
56
61
|
|
|
57
62
|
const to = this.toPoint
|
|
58
|
-
lineTo(to.x, to.y)
|
|
59
|
-
end()
|
|
63
|
+
lineTo(path, to.x, to.y)
|
|
60
64
|
}
|
|
61
65
|
|
|
62
66
|
public __updateBoxBounds(): void {
|
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, IPathString } from '@leafer-ui/interface'
|
|
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,5 +1,5 @@
|
|
|
1
1
|
import { __Number } from '@leafer/interface'
|
|
2
|
-
import {
|
|
2
|
+
import { PathCommandDataHelper, dataProcessor, pathType, registerUI } from '@leafer/core'
|
|
3
3
|
|
|
4
4
|
import { IPolygon, IPolygonData, IPolygonInputData } from '@leafer-ui/interface'
|
|
5
5
|
import { PolygonData } from '@leafer-ui/data'
|
|
@@ -8,12 +8,14 @@ import { UI } from './UI'
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
const { sin, cos, PI } = Math
|
|
11
|
-
const {
|
|
11
|
+
const { moveTo, lineTo, closePath } = PathCommandDataHelper
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@registerUI()
|
|
15
15
|
export class Polygon extends UI implements IPolygon {
|
|
16
16
|
|
|
17
|
+
public get __tag() { return 'Polygon' }
|
|
18
|
+
|
|
17
19
|
@dataProcessor(PolygonData)
|
|
18
20
|
public __: IPolygonData
|
|
19
21
|
|
|
@@ -29,14 +31,14 @@ export class Polygon extends UI implements IPolygon {
|
|
|
29
31
|
const { width, height, sides } = this.__
|
|
30
32
|
const rx = width / 2, ry = height / 2
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
moveTo(rx, 0)
|
|
34
|
+
const path: number[] = this.__.path = []
|
|
35
|
+
moveTo(path, rx, 0)
|
|
34
36
|
|
|
35
37
|
for (let i = 1; i < sides; i++) {
|
|
36
|
-
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))
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
closePath(path)
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
}
|
package/src/Rect.ts
CHANGED
package/src/Star.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __Number } from '@leafer/interface'
|
|
2
|
-
import {
|
|
2
|
+
import { PathCommandDataHelper, dataProcessor, pathType, registerUI } from '@leafer/core'
|
|
3
3
|
|
|
4
4
|
import { IStar, IStarData, IStarInputData } from '@leafer-ui/interface'
|
|
5
5
|
import { StarData } from '@leafer-ui/data'
|
|
@@ -8,19 +8,21 @@ import { UI } from './UI'
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
const { sin, cos, PI } = Math
|
|
11
|
-
const {
|
|
11
|
+
const { moveTo, lineTo, closePath } = PathCommandDataHelper
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@registerUI()
|
|
15
15
|
export class Star extends UI implements IStar {
|
|
16
16
|
|
|
17
|
+
public get __tag() { return 'Star' }
|
|
18
|
+
|
|
17
19
|
@dataProcessor(StarData)
|
|
18
20
|
public __: IStarData
|
|
19
21
|
|
|
20
22
|
@pathType(5)
|
|
21
23
|
public points: __Number
|
|
22
24
|
|
|
23
|
-
@pathType(0.
|
|
25
|
+
@pathType(0.382)
|
|
24
26
|
public innerRadius: __Number
|
|
25
27
|
|
|
26
28
|
constructor(data?: IStarInputData) {
|
|
@@ -32,14 +34,14 @@ export class Star extends UI implements IStar {
|
|
|
32
34
|
const { width, height, points, innerRadius } = this.__
|
|
33
35
|
const rx = width / 2, ry = height / 2
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
moveTo(rx, 0)
|
|
37
|
+
const path: number[] = this.__.path = []
|
|
38
|
+
moveTo(path, rx, 0)
|
|
37
39
|
|
|
38
40
|
for (let i = 1; i < points * 2; i++) {
|
|
39
|
-
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))
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
closePath(path)
|
|
43
45
|
|
|
44
46
|
}
|
|
45
47
|
|
package/src/Text.ts
CHANGED
|
@@ -1,24 +1,40 @@
|
|
|
1
|
-
import { IPathDrawer, IPathCommandData, __Boolean, __Number, __String } from '@leafer/interface'
|
|
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('
|
|
37
|
+
@boundsType('L')
|
|
22
38
|
public fontFamily: __String
|
|
23
39
|
|
|
24
40
|
@boundsType(12)
|
|
@@ -30,45 +46,108 @@ export class Text extends UI implements IText {
|
|
|
30
46
|
@boundsType(false)
|
|
31
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: __Number |
|
|
55
|
+
@boundsType(0)
|
|
56
|
+
public letterSpacing: __Number | IUnitData
|
|
41
57
|
|
|
42
|
-
@boundsType()
|
|
43
|
-
public lineHeight: __Number |
|
|
58
|
+
@boundsType({ type: 'percent', value: 150 } as IUnitData)
|
|
59
|
+
public lineHeight: __Number | IUnitData
|
|
44
60
|
|
|
45
|
-
@boundsType()
|
|
46
|
-
public
|
|
61
|
+
@boundsType(0)
|
|
62
|
+
public paraIndent: __Number
|
|
47
63
|
|
|
48
|
-
@boundsType()
|
|
49
|
-
public
|
|
64
|
+
@boundsType(0)
|
|
65
|
+
public paraSpacing: __Number
|
|
66
|
+
|
|
67
|
+
@boundsType('left')
|
|
68
|
+
public textAlign: ITextAlign
|
|
69
|
+
|
|
70
|
+
@boundsType('top')
|
|
71
|
+
public verticalAlign: IVerticalAlign
|
|
72
|
+
|
|
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
|
|
|
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
|
+
|
|
55
91
|
public __drawPathByData(drawer: IPathDrawer, _data: IPathCommandData): void {
|
|
56
|
-
const { width, height } = this.
|
|
57
|
-
drawer.rect(
|
|
92
|
+
const { x, y, width, height } = this.__layout.boxBounds
|
|
93
|
+
drawer.rect(x, y, width, height)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public __drawRenderPath(canvas: ILeaferCanvas): void {
|
|
97
|
+
canvas.font = this.__.__font
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public __updateTextDrawData(): void {
|
|
101
|
+
const data = this.__
|
|
102
|
+
data.__textDrawData = TextConvert.getDrawData(data.text, this.__)
|
|
103
|
+
|
|
58
104
|
}
|
|
59
105
|
|
|
60
106
|
public __updateBoxBounds(): void {
|
|
61
|
-
const { fontFamily, fontSize, fontWeight, italic, textCase, lineHeight } = this.__
|
|
62
|
-
const b = this.__layout.boxBounds
|
|
63
107
|
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
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
|
+
}
|
|
67
148
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
b.width = width
|
|
71
|
-
b.height = height
|
|
149
|
+
public __updateRenderBounds(): void {
|
|
150
|
+
copyAndSpread(this.__layout.renderBounds, this.__layout.contentBounds, this.__layout.renderSpread)
|
|
72
151
|
}
|
|
73
152
|
|
|
74
153
|
}
|
package/src/UI.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { ILeaferCanvas, IPathDrawer, IPathCommandData,
|
|
2
|
-
import { Leaf,
|
|
1
|
+
import { ILeaferCanvas, IPathDrawer, IPathCommandData, IHitType, __Number, __Boolean, __String, IPathString } 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, IStrokeWidthString, ICornerRadiusString } from '@leafer-ui/interface'
|
|
4
|
+
import { IUI, IShadowEffect, IBlurEffect, IPaint, IStrokeAlign, IStrokeJoin, IStrokeCap, IBlendMode, IPaintString, IDashPatternString, IShadowString, IGrayscaleEffect, IUIData, IGroup, IStrokeWidthString, ICornerRadiusString, IUITagInputData, IUIInputData } 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,21 +88,28 @@ 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
|
|
|
@@ -102,28 +118,28 @@ export class UI extends Leaf implements IUI {
|
|
|
102
118
|
|
|
103
119
|
// stroke
|
|
104
120
|
|
|
105
|
-
@
|
|
121
|
+
@strokeType()
|
|
106
122
|
public stroke: IPaint | IPaint[] | IPaintString
|
|
107
123
|
|
|
108
|
-
@
|
|
124
|
+
@strokeType('inside')
|
|
109
125
|
public strokeAlign: IStrokeAlign
|
|
110
126
|
|
|
111
|
-
@
|
|
127
|
+
@strokeType(1)
|
|
112
128
|
public strokeWidth: number | number[] | IStrokeWidthString
|
|
113
129
|
|
|
114
|
-
@
|
|
130
|
+
@strokeType('none')
|
|
115
131
|
public strokeCap: IStrokeCap
|
|
116
132
|
|
|
117
|
-
@
|
|
133
|
+
@strokeType('miter')
|
|
118
134
|
public strokeJoin: IStrokeJoin
|
|
119
135
|
|
|
120
|
-
@
|
|
136
|
+
@strokeType()
|
|
121
137
|
public dashPattern: __Number[] | IDashPatternString
|
|
122
138
|
|
|
123
|
-
@
|
|
139
|
+
@strokeType()
|
|
124
140
|
public dashOffset: __Number
|
|
125
141
|
|
|
126
|
-
@
|
|
142
|
+
@strokeType(10)
|
|
127
143
|
public miterLimit: __Number
|
|
128
144
|
|
|
129
145
|
|
|
@@ -153,23 +169,43 @@ export class UI extends Leaf implements IUI {
|
|
|
153
169
|
public grayscale: __Number | IGrayscaleEffect
|
|
154
170
|
|
|
155
171
|
|
|
156
|
-
|
|
172
|
+
constructor(data?: IUIInputData) {
|
|
173
|
+
super(data)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
public set(data: IUITagInputData): void {
|
|
178
|
+
Object.assign(this, data)
|
|
179
|
+
}
|
|
157
180
|
|
|
158
|
-
public get
|
|
181
|
+
public get(): IUITagInputData {
|
|
182
|
+
return this.__.__getInputData()
|
|
183
|
+
}
|
|
159
184
|
|
|
160
|
-
public get relativeTransform(): IMatrixData { return this.__layout.getTransform('relative') }
|
|
161
185
|
|
|
162
|
-
|
|
186
|
+
public getPath(curve?: boolean): IPathCommandData {
|
|
187
|
+
const path = this.__.path
|
|
188
|
+
if (!path) return []
|
|
189
|
+
return curve ? PathConvert.toCanvasData(path, true) : path
|
|
190
|
+
}
|
|
163
191
|
|
|
164
|
-
public
|
|
192
|
+
public getPathString(curve?: boolean): IPathString {
|
|
193
|
+
return PathConvert.stringify(this.getPath(curve))
|
|
194
|
+
}
|
|
165
195
|
|
|
166
|
-
public get worldRenderBounds(): IBoundsData { return this.__layout.getBounds('world', 'render') }
|
|
167
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
|
+
}
|
|
168
204
|
|
|
169
205
|
public __updateRenderPath(): void {
|
|
170
206
|
if (this.__.path) {
|
|
171
207
|
const { __: data } = this
|
|
172
|
-
data.__pathForRender = data.cornerRadius ?
|
|
208
|
+
data.__pathForRender = data.cornerRadius ? PathCorner.smooth(data.path, data.cornerRadius, data.cornerSmoothing) : data.path
|
|
173
209
|
}
|
|
174
210
|
}
|
|
175
211
|
|
|
@@ -183,7 +219,11 @@ export class UI extends Leaf implements IUI {
|
|
|
183
219
|
this.__drawPathByData(canvas, this.__.path)
|
|
184
220
|
}
|
|
185
221
|
|
|
186
|
-
@rewrite(
|
|
222
|
+
@rewrite(PathDrawer.drawPathByData)
|
|
187
223
|
public __drawPathByData(_drawer: IPathDrawer, _data: IPathCommandData): void { }
|
|
188
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
|
+
}
|
|
228
|
+
|
|
189
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
|
-
}
|