@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leafer-ui/display",
3
- "version": "1.0.0-alpha.7",
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-alpha.7",
23
- "@leafer-ui/data": "1.0.0-alpha.7",
24
- "@leafer-ui/display-module": "1.0.0-alpha.7",
25
- "@leafer-ui/decorator": "1.0.0-alpha.7"
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-alpha.7",
29
- "@leafer-ui/interface": "1.0.0-alpha.7"
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 { PathCreator, OneRadian, dataProcessor, pathType, registerUI } from '@leafer/core'
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 { PI } = Math
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: number
21
+ public innerRadius: __Number
21
22
 
22
23
  @pathType(0)
23
- public startAngle: number
24
+ public startAngle: __Number
24
25
 
25
26
  @pathType(0)
26
- public endAngle: number
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
- begin(this.__.path = [])
38
+ const path: number[] = this.__.path = []
38
39
 
39
40
  if (innerRadius) {
40
41
 
41
42
  if (startAngle || endAngle) {
42
- ellipse(rx, ry, rx * (1 - innerRadius), ry * (1 - innerRadius), 0, startAngle * OneRadian, endAngle * OneRadian, false)
43
- ellipse(rx, ry, rx, ry, 0, endAngle * OneRadian, startAngle * OneRadian, true)
44
- close()
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
- ellipse(rx, ry, rx * (1 - innerRadius), ry * (1 - innerRadius), 0, 0, 2 * PI, false)
47
- moveTo(width, ry)
48
- ellipse(rx, ry, rx, ry, 0, 0, 2 * PI, true)
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 * OneRadian, endAngle * OneRadian, false)
56
- close()
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, 0, 0, 2 * PI, false)
61
+ ellipse(path, rx, ry, rx, ry)
59
62
  }
60
63
 
61
64
  }
package/src/Frame.ts CHANGED
@@ -1,84 +1,25 @@
1
- import { ILeaferCanvas, IRenderOptions, ICanvasDrawPath, IBoundsData, IPathCommandData } from '@leafer/interface'
2
- import { BoundsHelper, dataProcessor, boundsType, rewrite, useModule, rewriteAble, registerUI } from '@leafer/core'
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 { Group } from './Group'
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 Group implements IFrame {
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
- @boundsType(true)
27
- public clip: boolean
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.__isBranch = true
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
- public remove(_child?: IUI): void { } // Branch rewrite
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 { boundsType, dataProcessor, registerUI } from '@leafer/core'
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: string
19
+ public url: __String
17
20
 
18
- @boundsType('')
19
- public thumb: string
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 { __Number, IPointData, ITwoPointBoundsData } from '@leafer/interface'
2
- import { PathCreator, PointHelper, TwoPointBoundsHelper, boundsType, dataProcessor, registerUI } from '@leafer/core'
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 { begin, moveTo, lineTo, end } = PathCreator
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 __to: IPointData
31
+ protected __toPoint: IPointData
28
32
 
29
33
  public get toPoint(): IPointData {
30
- if (this.__to && !this.__layout.boxBoundsChanged) return this.__to
34
+ if (this.__toPoint && !this.__layout.boxChanged) return this.__toPoint
31
35
 
32
- const { width, height, rotation } = this.__
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.__to = to
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
- begin(this.__.path = [])
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.__to.x, this.__to.y)
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 { ITwoPointBoundsData, ILeaferCanvas, IPathCommandData } from '@leafer/interface'
2
- import { PathHelper, TwoPointBoundsHelper, dataProcessor, pathType, registerUI } from '@leafer/core'
1
+ import { IPathCommandData, IWindingRule } from '@leafer/interface'
2
+ import { PathBounds, dataProcessor, pathType, affectStrokeBoundsType, registerUI } from '@leafer/core'
3
3
 
4
- import { IPath, IPathData, IPathInputData, IWindingRule, 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 { toTwoPointBounds } = PathHelper
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
- toTwoPointBounds(this.__.path, pointBounds)
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 { PathCreator, dataProcessor, pathType, registerUI } from '@leafer/core'
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 { begin, moveTo, lineTo, close } = PathCreator
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
- begin(this.__.path = [])
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
- close()
41
+ closePath(path)
39
42
  }
40
43
 
41
44
  }
package/src/Rect.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ICanvasDrawPath, IPathCommandData } from '@leafer/interface'
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 __updatePath(): void { }
23
-
24
- public __drawPathByData(drawer: ICanvasDrawPath, _data: IPathCommandData): void {
25
- const { width, height, borderRadius } = this.__
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 { PathCreator, dataProcessor, pathType, registerUI } from '@leafer/core'
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 { begin, moveTo, lineTo, close } = PathCreator
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: number
23
+ public points: __Number
21
24
 
22
- @pathType(0.38)
23
- public innerRadius: number
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
- begin(this.__.path = [])
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
- close()
44
+ closePath(path)
42
45
 
43
46
  }
44
47
 
package/src/Text.ts CHANGED
@@ -1,78 +1,153 @@
1
- import { ICanvasDrawPath, IPathCommandData } from '@leafer/interface'
2
- import { Platform, boundsType, dataProcessor, registerUI, useModule } from '@leafer/core'
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, IPercent, ITextData, ITextInputData } from '@leafer-ui/interface'
5
- import { TextData } from '@leafer-ui/data'
6
- import { TextRender } from '@leafer-ui/display-module'
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
- @useModule(TextRender)
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 content: string
35
+ public text: __String
20
36
 
21
- @boundsType('arial')
22
- public fontFamily: string
37
+ @boundsType('L')
38
+ public fontFamily: __String
23
39
 
24
40
  @boundsType(12)
25
- public fontSize: number
41
+ public fontSize: __Number
26
42
 
27
43
  @boundsType('normal')
28
44
  public fontWeight: IFontWeight
29
45
 
30
46
  @boundsType(false)
31
- public italic: boolean
47
+ public italic: __Boolean
32
48
 
33
- @boundsType('normal')
49
+ @boundsType('none')
34
50
  public textCase: ITextCase
35
51
 
36
- @boundsType('normal')
52
+ @boundsType('none')
37
53
  public textDecoration: ITextDecoration
38
54
 
39
- @boundsType()
40
- public letterSpacing: number | IPercent
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 lineHeight: number | IPercent
67
+ @boundsType('left')
68
+ public textAlign: ITextAlign
44
69
 
45
- @boundsType()
46
- public paragraphIndent: number
70
+ @boundsType('top')
71
+ public verticalAlign: IVerticalAlign
47
72
 
48
- @boundsType()
49
- public paragraphSpacing: number
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 __updatePath(): void {
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 __drawPathByData(drawer: ICanvasDrawPath, _data: IPathCommandData): void {
60
- const { width, height } = this.__
61
- drawer.rect(0, 0, width, height)
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
- this.__.__font = Platform.canvas.font = `${italic ? 'italic' : ''} ${textCase === 'small-caps' ? 'small-caps' : 'normal'} ${fontWeight ? fontWeight : 'normal'} ${fontSize}px/${lineHeight ? lineHeight : fontSize}px ${fontFamily}`
69
- const width = Platform.canvas.measureText(this.content).width
70
- const height = fontSize
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
- b.x = 0
73
- b.y = -fontSize * 0.75
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, ICanvasDrawPath, IPathCommandData, __Number, __Boolean, __String, IMatrixData, IBoundsData } from '@leafer/interface'
2
- import { Leaf, PathHelper, affectEventBoundsType, surfaceType, dataType, positionType, boundsType, pathType, scaleType, rotationType, opacityType, sortType, dataProcessor, useModule, rewrite, rewriteAble } from '@leafer/core'
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, IBorderWidthString, IBorderRadiusString } from '@leafer-ui/interface'
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
- // layer
102
+ @strokeType('path')
103
+ public hitStroke: IHitType
88
104
 
89
- @surfaceType() // "pass-through"
90
- public blendMode: IBlendMode
105
+ @hitType(true)
106
+ public hitChildren: __Boolean
91
107
 
92
- @boundsType()
93
- public mask: __Boolean
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
- @affectEventBoundsType()
121
+ @strokeType()
115
122
  public stroke: IPaint | IPaint[] | IPaintString
116
123
 
117
- @affectEventBoundsType('center')
124
+ @strokeType('inside')
118
125
  public strokeAlign: IStrokeAlign
119
126
 
120
- @affectEventBoundsType(1)
121
- public strokeWidth: __Number
127
+ @strokeType(1)
128
+ public strokeWidth: number | number[] | IStrokeWidthString
122
129
 
123
- @surfaceType('none')
130
+ @strokeType('none')
124
131
  public strokeCap: IStrokeCap
125
132
 
126
- @surfaceType('miter')
133
+ @strokeType('miter')
127
134
  public strokeJoin: IStrokeJoin
128
135
 
129
- @surfaceType()
136
+ @strokeType()
130
137
  public dashPattern: __Number[] | IDashPatternString
131
138
 
132
- @surfaceType()
139
+ @strokeType()
133
140
  public dashOffset: __Number
134
141
 
135
- @surfaceType(10)
142
+ @strokeType(10)
136
143
  public miterLimit: __Number
137
144
 
138
145
 
139
146
  // corner
140
147
 
141
148
  @pathType()
142
- public cornerRadius: __Number
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
- // now transform
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 worldTransform(): IMatrixData { return this.__layout.getTransform('world') }
181
+ public get(): IUITagInputData {
182
+ return this.__.__getInputData()
183
+ }
168
184
 
169
- public get relativeTransform(): IMatrixData { return this.__layout.getTransform('relative') }
170
185
 
171
- // now bounds
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 get worldBoxBounds(): IBoundsData { return this.__layout.getBounds('world', 'box') }
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
- const { __: data } = this
180
- const { cornerRadius, path } = data
181
- data.__renderPath = cornerRadius && path ? PathHelper.applyCorner(path, cornerRadius, data.cornerSmoothing) : path
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.__.__renderPath)
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(PathHelper.drawData)
195
- public __drawPathByData(_drawer: ICanvasDrawPath, _data: IPathCommandData): void { }
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
- export { Path } from './Path'
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
- }