@leafer-ui/display 1.0.0-alpha.23 → 1.0.0-alpha.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leafer-ui/display",
3
- "version": "1.0.0-alpha.23",
3
+ "version": "1.0.0-alpha.30",
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.23",
23
- "@leafer-ui/data": "1.0.0-alpha.23",
24
- "@leafer-ui/display-module": "1.0.0-alpha.23",
25
- "@leafer-ui/decorator": "1.0.0-alpha.23"
22
+ "@leafer/core": "1.0.0-alpha.30",
23
+ "@leafer-ui/data": "1.0.0-alpha.30",
24
+ "@leafer-ui/display-module": "1.0.0-alpha.30",
25
+ "@leafer-ui/decorator": "1.0.0-alpha.30"
26
26
  },
27
27
  "devDependencies": {
28
- "@leafer/interface": "1.0.0-alpha.23",
29
- "@leafer-ui/interface": "1.0.0-alpha.23"
28
+ "@leafer/interface": "1.0.0-alpha.30",
29
+ "@leafer-ui/interface": "1.0.0-alpha.30"
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.renderBoundsChanged || this.__layout.renderBoundsChange()
32
+ }
33
+
34
+ @rewrite(rect.__updateStrokeBoundsSpreadWidth)
35
+ public __updateStrokeBoundsSpreadWidth(): number { return 0 }
36
+
37
+ @rewrite(rect.__updateRenderBoundsSpreadWidth)
38
+ public __updateRectRenderBoundsSpreadWidth(): number { return 0 }
39
+
40
+ public __updateRenderBoundsSpreadWidth(): number {
41
+ let width = this.__updateRectRenderBoundsSpreadWidth() || super.__updateRenderBoundsSpreadWidth()
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,60 @@
1
+ import { ILeaferCanvas, ILeaferCanvasConfig, __String, IRenderOptions, IPointData, ICanvasContext2D, IScreenSizeData } from '@leafer/interface'
2
+ import { Creator, Matrix, boundsType, dataProcessor, registerUI, surfaceType } 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
+
9
+
10
+ @registerUI()
11
+ export class Canvas extends Rect implements ICanvas {
12
+
13
+ public get __tag() { return 'Canvas' }
14
+
15
+ @dataProcessor(ImageData)
16
+ public __: ICanvasData
17
+
18
+ @boundsType('')
19
+ public pixelRatio: number
20
+
21
+ @surfaceType('true')
22
+ public smooth: boolean
23
+
24
+ public canvas: ILeaferCanvas
25
+
26
+ public readonly context: ICanvasContext2D
27
+
28
+ constructor(data?: ICanvasInputData) {
29
+ super(data)
30
+ this.canvas = Creator.canvas(data as ILeaferCanvasConfig)
31
+ this.context = this.canvas.context
32
+ this.__.hitType = 'all'
33
+ this.__.pixelRatio = this.canvas.pixelRatio
34
+ }
35
+
36
+ public draw(ui: IUI, offset?: IPointData, scale?: number | IPointData, rotation?: number): void {
37
+ ui.__layout.checkUpdate()
38
+ const matrix = new Matrix(ui.__world)
39
+ matrix.invert()
40
+
41
+ const m = new Matrix()
42
+ if (offset) m.translate(offset.x, offset.y)
43
+ if (scale) typeof scale === 'number' ? m.scale(scale) : m.scale(scale.x, scale.y)
44
+ if (rotation) m.rotate(rotation)
45
+ matrix.preMultiply(m)
46
+
47
+ ui.__render(this.canvas, { matrix })
48
+ this.forceUpdate('fill')
49
+ }
50
+
51
+ public __draw(canvas: ILeaferCanvas, _options: IRenderOptions): void {
52
+ canvas.drawImage(this.canvas.view as any, 0, 0)
53
+ }
54
+
55
+ public __updateBoxBounds(): void {
56
+ super.__updateBoxBounds()
57
+ this.canvas.resize(this.__ as IScreenSizeData)
58
+ }
59
+
60
+ }
package/src/Ellipse.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { __Number } from '@leafer/interface'
2
- import { PathCreator, OneRadian, dataProcessor, pathType, registerUI } from '@leafer/core'
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,9 +7,7 @@ import { EllipseData } from '@leafer-ui/data'
7
7
  import { UI } from './UI'
8
8
 
9
9
 
10
- const { PI } = Math
11
- const { begin, moveTo, close, ellipse } = PathCreator
12
-
10
+ const { moveTo, closePath, ellipse } = PathCommandDataHelper
13
11
 
14
12
  @registerUI()
15
13
  export class Ellipse extends UI implements IEllipse {
@@ -37,30 +35,30 @@ export class Ellipse extends UI implements IEllipse {
37
35
  const { width, height, innerRadius, startAngle, endAngle } = this.__
38
36
  const rx = width / 2, ry = height / 2
39
37
 
40
- begin(this.__.path = [])
38
+ const path: number[] = this.__.path = []
41
39
 
42
40
  if (innerRadius) {
43
41
 
44
42
  if (startAngle || endAngle) {
45
- if (innerRadius < 1) ellipse(rx, ry, rx * innerRadius, ry * innerRadius, 0, startAngle * OneRadian, endAngle * OneRadian, false)
46
- ellipse(rx, ry, rx, ry, 0, endAngle * OneRadian, startAngle * OneRadian, true)
47
- if (innerRadius < 1) 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)
48
46
  } else {
49
47
  if (innerRadius < 1) {
50
- ellipse(rx, ry, rx * innerRadius, ry * innerRadius, 0, 0, 2 * PI, false)
51
- moveTo(width, ry)
48
+ ellipse(path, rx, ry, rx * innerRadius, ry * innerRadius)
49
+ moveTo(path, width, ry)
52
50
  }
53
- ellipse(rx, ry, rx, ry, 0, 0, 2 * PI, true)
51
+ ellipse(path, rx, ry, rx, ry, 0, 0, 360, true)
54
52
  }
55
53
 
56
54
  } else {
57
55
 
58
56
  if (startAngle || endAngle) {
59
- moveTo(rx, ry)
60
- ellipse(rx, ry, rx, ry, 0, startAngle * OneRadian, endAngle * OneRadian, false)
61
- close()
57
+ moveTo(path, rx, ry)
58
+ ellipse(path, rx, ry, rx, ry, 0, startAngle, endAngle, false)
59
+ closePath(path)
62
60
  } else {
63
- ellipse(rx, ry, rx, ry, 0, 0, 2 * PI, false)
61
+ ellipse(path, rx, ry, rx, ry)
64
62
  }
65
63
 
66
64
  }
package/src/Frame.ts CHANGED
@@ -1,86 +1,25 @@
1
- import { ILeaferCanvas, IRenderOptions, IPathDrawer, IBoundsData, IPathCommandData, __Boolean } 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 {
22
12
 
23
13
  public get __tag() { return 'Frame' }
24
14
 
25
15
  @dataProcessor(FrameData)
26
16
  public __: IFrameData
27
17
 
28
- @boundsType(true)
29
- public clip: __Boolean
18
+ @affectRenderBoundsType('hide')
19
+ public overflow: IOverflow
30
20
 
31
21
  constructor(data?: IFrameInputData) {
32
22
  super(data)
33
- if (!this.fill) this.fill = '#FFFFFF'
34
- this.__isBranchLeaf = true
35
- }
36
-
37
- @rewrite(rect.__drawPathByData)
38
- public __drawPathByData(_drawer: IPathDrawer, _data: IPathCommandData): void { }
39
-
40
- public __updateBoxBounds(): void {
41
- this.__updateRectBoxBounds()
42
- if (!this.__.clip) {
43
- const { boxBounds } = this.__layout
44
- copy(bounds, boxBounds)
45
- super.__updateBoxBounds()
46
- add(boxBounds, bounds)
47
- }
48
- }
49
-
50
- public __updateStrokeBounds(): void {
51
- this.__updateRectStrokeBounds()
52
- if (!this.__.clip) {
53
- const { strokeBounds: eventBounds } = this.__layout
54
- copy(bounds, eventBounds)
55
- super.__updateStrokeBounds()
56
- add(eventBounds, bounds)
57
- }
58
- }
59
-
60
- public __updateRenderBounds(): void {
61
- this.__updateRectRenderBounds()
62
- if (!this.__.clip) {
63
- const { renderBounds } = this.__layout
64
- copy(bounds, renderBounds)
65
- super.__updateRenderBounds()
66
- add(renderBounds, bounds)
67
- }
23
+ if (!this.__.fill) this.__.fill = '#FFFFFF'
68
24
  }
69
-
70
- @rewrite(rect.__updateBoxBounds)
71
- public __updateRectBoxBounds(): void { }
72
-
73
- @rewrite(rect.__updateStrokeBounds)
74
- public __updateRectStrokeBounds(): void { }
75
-
76
- @rewrite(rect.__updateRenderBounds)
77
- public __updateRectRenderBounds(): void { }
78
-
79
-
80
- @rewrite(rect.__render)
81
- public __renderRect(_canvas: ILeaferCanvas, _options: IRenderOptions): void { }
82
-
83
- @rewrite(group.__render)
84
- public __renderGroup(_canvas: ILeaferCanvas, _options: IRenderOptions): void { }
85
-
86
25
  }
package/src/Group.ts CHANGED
@@ -30,7 +30,7 @@ export class Group extends UI implements IGroup {
30
30
 
31
31
  constructor(data?: IGroupInputData) {
32
32
  super(data)
33
- this.__isBranch = true
33
+ this.isBranch = true
34
34
  this.children = []
35
35
  }
36
36
 
@@ -52,20 +52,4 @@ export class Group extends UI implements IGroup {
52
52
 
53
53
  public remove(_child?: IUI): void { }
54
54
 
55
- protected __removeMask(child?: IUI): void {
56
- if (child) {
57
- child.isMask = false
58
- this.remove(child)
59
- } else {
60
- const { children } = this
61
- for (let i = 0, len = children.length; i < len; i++) {
62
- child = children[i]
63
- if (child.isMask) {
64
- child.isMask = false
65
- this.remove(child)
66
- len--, i--
67
- }
68
- }
69
- }
70
- }
71
55
  }
package/src/Image.ts CHANGED
@@ -31,9 +31,10 @@ export class Image extends Rect implements IImage {
31
31
  let update: boolean
32
32
 
33
33
  const { url } = this
34
- const fills = this.fill as IImagePaint[]
35
- if (fills) {
36
- if (fills[0].url !== url) update = true
34
+ const fill = this.fill as IImagePaint
35
+
36
+ if (fill) {
37
+ if (fill.url !== url) update = true
37
38
  } else {
38
39
  if (url) update = true
39
40
  }
package/src/Line.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IPointData, ITwoPointBoundsData, __Number } from '@leafer/interface'
2
- import { PathCreator, PointHelper, TwoPointBoundsHelper, boundsType, affectEventBoundsType, dataProcessor, registerUI } from '@leafer/core'
2
+ import { PathCommandDataHelper, PointHelper, TwoPointBoundsHelper, boundsType, affectStrokeBoundsType, dataProcessor, registerUI } from '@leafer/core'
3
3
 
4
4
  import { ILine, ILineData, ILineInputData, IStrokeAlign } from '@leafer-ui/interface'
5
5
  import { LineData } from '@leafer-ui/data'
@@ -7,7 +7,7 @@ import { LineData } from '@leafer-ui/data'
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
 
@@ -25,7 +25,7 @@ export class Line extends UI implements ILine {
25
25
  @boundsType()
26
26
  public rotation: __Number
27
27
 
28
- @affectEventBoundsType('center')
28
+ @affectStrokeBoundsType('center')
29
29
  public strokeAlign: IStrokeAlign
30
30
 
31
31
  protected __toPoint: IPointData
@@ -56,12 +56,11 @@ export class Line extends UI implements ILine {
56
56
 
57
57
  public __updatePath(): void {
58
58
 
59
- begin(this.__.path = [])
60
- moveTo(0, 0)
59
+ const path: number[] = this.__.path = []
60
+ moveTo(path, 0, 0)
61
61
 
62
62
  const to = this.toPoint
63
- lineTo(to.x, to.y)
64
- end()
63
+ lineTo(path, to.x, to.y)
65
64
  }
66
65
 
67
66
  public __updateBoxBounds(): void {
package/src/Path.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { ILeaferCanvas, IPathCommandData, IWindingRule } from '@leafer/interface'
2
- import { PathHelper, dataProcessor, pathType, affectEventBoundsType, registerUI } from '@leafer/core'
1
+ import { IPathCommandData, IWindingRule } from '@leafer/interface'
2
+ import { PathBounds, dataProcessor, pathType, affectStrokeBoundsType, registerUI, PathConvert } from '@leafer/core'
3
3
 
4
4
  import { IPath, IPathData, IPathInputData, IPathString, IStrokeAlign } from '@leafer-ui/interface'
5
5
  import { PathData } from '@leafer-ui/data'
@@ -7,7 +7,7 @@ import { PathData } from '@leafer-ui/data'
7
7
  import { UI } from './UI'
8
8
 
9
9
 
10
- const { toBounds } = PathHelper
10
+ const { toBounds } = PathBounds
11
11
 
12
12
  @registerUI()
13
13
  export class Path extends UI implements IPath {
@@ -23,16 +23,21 @@ export class Path extends UI implements IPath {
23
23
  @pathType()
24
24
  public windingRule: IWindingRule
25
25
 
26
- @affectEventBoundsType('center')
26
+ @affectStrokeBoundsType('center')
27
27
  public strokeAlign: IStrokeAlign
28
28
 
29
29
  constructor(data?: IPathInputData) {
30
30
  super(data)
31
31
  }
32
32
 
33
- public __drawRenderPath(canvas: ILeaferCanvas): void {
34
- canvas.beginPath()
35
- this.__drawPathByData(canvas, this.__.path)
33
+ public getCurvePath(): IPathCommandData {
34
+ return PathConvert.toCanvasData(this.__.path, true)
35
+ }
36
+
37
+ public getStringPath(curve?: boolean): IPathString {
38
+ let path = this.__.path
39
+ if (curve) path = PathConvert.toCanvasData([...path], true)
40
+ return PathConvert.stringify(path)
36
41
  }
37
42
 
38
43
  public __updateBoxBounds(): void {
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 { PathCreator, dataProcessor, pathType, registerUI } from '@leafer/core'
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,7 +8,7 @@ import { UI } from './UI'
8
8
 
9
9
 
10
10
  const { sin, cos, PI } = Math
11
- const { begin, moveTo, lineTo, close } = PathCreator
11
+ const { moveTo, lineTo, closePath } = PathCommandDataHelper
12
12
 
13
13
 
14
14
  @registerUI()
@@ -31,14 +31,14 @@ export class Polygon extends UI implements IPolygon {
31
31
  const { width, height, sides } = this.__
32
32
  const rx = width / 2, ry = height / 2
33
33
 
34
- begin(this.__.path = [])
35
- moveTo(rx, 0)
34
+ const path: number[] = this.__.path = []
35
+ moveTo(path, rx, 0)
36
36
 
37
37
  for (let i = 1; i < sides; i++) {
38
- 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))
39
39
  }
40
40
 
41
- close()
41
+ closePath(path)
42
42
  }
43
43
 
44
44
  }
package/src/Star.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { __Number } from '@leafer/interface'
2
- import { PathCreator, dataProcessor, pathType, registerUI } from '@leafer/core'
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,7 +8,7 @@ import { UI } from './UI'
8
8
 
9
9
 
10
10
  const { sin, cos, PI } = Math
11
- const { begin, moveTo, lineTo, close } = PathCreator
11
+ const { moveTo, lineTo, closePath } = PathCommandDataHelper
12
12
 
13
13
 
14
14
  @registerUI()
@@ -34,14 +34,14 @@ export class Star extends UI implements IStar {
34
34
  const { width, height, points, innerRadius } = this.__
35
35
  const rx = width / 2, ry = height / 2
36
36
 
37
- begin(this.__.path = [])
38
- moveTo(rx, 0)
37
+ const path: number[] = this.__.path = []
38
+ moveTo(path, rx, 0)
39
39
 
40
40
  for (let i = 1; i < points * 2; i++) {
41
- 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))
42
42
  }
43
43
 
44
- close()
44
+ closePath(path)
45
45
 
46
46
  }
47
47
 
package/src/Text.ts CHANGED
@@ -1,13 +1,16 @@
1
- import { IPathDrawer, IPathCommandData, __Boolean, __Number, __String } from '@leafer/interface'
2
- import { boundsType, dataProcessor, registerUI, surfaceType, useModule } from '@leafer/core'
1
+ import { ILeaferCanvas, IPathDrawer, IPathCommandData, __Boolean, __Number, __String } from '@leafer/interface'
2
+ import { BoundsHelper, boundsType, dataProcessor, registerUI, useModule, affectStrokeBoundsType } from '@leafer/core'
3
3
 
4
- import { IText, IFontWeight, ITextCase, ITextDecoration, IPercent, ITextData, ITextInputData, ITextAlign, IVerticalAlign, ITextDrawData } from '@leafer-ui/interface'
5
- import { TextData } from '@leafer-ui/data'
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
6
  import { TextRender } from '@leafer-ui/display-module'
7
7
  import { TextConvert } from '@leafer-ui/text'
8
8
 
9
9
  import { UI } from './UI'
10
10
 
11
+
12
+ const { copyAndSpread, includes, spread } = BoundsHelper
13
+
11
14
  @useModule(TextRender)
12
15
  @registerUI()
13
16
  export class Text extends UI implements IText {
@@ -18,16 +21,22 @@ export class Text extends UI implements IText {
18
21
  public __: ITextData
19
22
 
20
23
  // size
21
- @boundsType(undefined)
24
+ @boundsType(0)
22
25
  public width: __Number
23
26
 
24
- @boundsType(undefined)
27
+ @boundsType(0)
25
28
  public height: __Number
26
29
 
30
+ @boundsType(0)
31
+ public padding: number | number[]
32
+
33
+ @affectStrokeBoundsType('outside')
34
+ public strokeAlign: IStrokeAlign
35
+
27
36
  @boundsType('')
28
- public content: __String
37
+ public text: __String
29
38
 
30
- @boundsType('arial')
39
+ @boundsType('L')
31
40
  public fontFamily: __String
32
41
 
33
42
  @boundsType(12)
@@ -39,36 +48,35 @@ export class Text extends UI implements IText {
39
48
  @boundsType(false)
40
49
  public italic: __Boolean
41
50
 
42
- @boundsType('normal')
51
+ @boundsType('none')
43
52
  public textCase: ITextCase
44
53
 
45
54
  @boundsType('none')
46
55
  public textDecoration: ITextDecoration
47
56
 
48
- @boundsType()
49
- public letterSpacing: __Number | IPercent
57
+ @boundsType(0)
58
+ public letterSpacing: __Number | IUnitData
50
59
 
51
- @boundsType(1)
52
- public lineHeight: __Number | IPercent
60
+ @boundsType({ type: 'percent', value: 150 } as IUnitData)
61
+ public lineHeight: __Number | IUnitData
53
62
 
54
- @boundsType()
55
- public paragraphIndent: __Number
63
+ @boundsType(0)
64
+ public paraIndent: __Number
56
65
 
57
- @boundsType()
58
- public paragraphSpacing: __Number
66
+ @boundsType(0)
67
+ public paraSpacing: __Number
59
68
 
60
- @surfaceType('left')
69
+ @boundsType('left')
61
70
  public textAlign: ITextAlign
62
71
 
63
- @surfaceType('top')
72
+ @boundsType('top')
64
73
  public verticalAlign: IVerticalAlign
65
74
 
66
- public get realWidth(): number { return this.textDrawData.width }
67
-
68
- public get realHeight(): number { return this.textDrawData.height }
75
+ @boundsType('show')
76
+ public textOverflow: IOverflow | string
69
77
 
70
78
  public get textDrawData(): ITextDrawData {
71
- this.__updateTextDrawData()
79
+ this.__layout.checkUpdate()
72
80
  return this.__.__textDrawData
73
81
  }
74
82
 
@@ -76,26 +84,68 @@ export class Text extends UI implements IText {
76
84
  super(data)
77
85
  }
78
86
 
87
+ public __drawHitPath(canvas: ILeaferCanvas): void {
88
+ const { __lineHeight, __baseLine, __textDrawData: data } = this.__
89
+ canvas.beginPath()
90
+ data.rows.forEach(row => canvas.rect(row.x, row.y - __baseLine, row.width, __lineHeight))
91
+ }
92
+
79
93
  public __drawPathByData(drawer: IPathDrawer, _data: IPathCommandData): void {
80
- const { width, height } = this.__
81
- drawer.rect(0, 0, width, height)
94
+ const { x, y, width, height } = this.__layout.boxBounds
95
+ drawer.rect(x, y, width, height)
82
96
  }
83
97
 
84
98
  public __updateTextDrawData(): void {
85
- this.__.__textDrawData || (this.__.__textDrawData = TextConvert.getDrawData(this.__.content, this.__))
99
+ const data = this.__
100
+ data.__textDrawData = TextConvert.getDrawData(data.text, this.__)
101
+
86
102
  }
87
103
 
88
104
  public __updateBoxBounds(): void {
89
105
 
106
+ const data = this.__
107
+ const layout = this.__layout
108
+ const { width, height, lineHeight, letterSpacing, fontFamily, fontSize, fontWeight, italic } = data
109
+
110
+ // compute
111
+
112
+ data.__lineHeight = UnitConvert.number(lineHeight, fontSize)
113
+ data.__letterSpacing = UnitConvert.number(letterSpacing, fontSize)
114
+ data.__baseLine = data.__lineHeight - (data.__lineHeight - fontSize * 0.7) / 2
115
+ data.__font = `${italic ? 'italic ' : ''}${fontWeight !== 'normal' ? fontWeight + ' ' : ''}${fontSize}px ${fontFamily}`
116
+
90
117
  this.__updateTextDrawData()
91
118
 
92
- const { width, height, __textDrawData: data } = this.__
93
- const b = this.__layout.boxBounds
119
+ const { bounds } = data.__textDrawData
120
+ const b = layout.boxBounds
121
+
122
+ if (data.__lineHeight < fontSize) spread(bounds, fontSize / 2)
123
+
124
+ if (width && height) {
125
+ super.__updateBoxBounds()
126
+ } else {
127
+ b.x = width ? 0 : bounds.x
128
+ b.y = height ? 0 : bounds.y
129
+ b.width = width ? width : bounds.width
130
+ b.height = height ? height : bounds.height
131
+ }
132
+
133
+ const contentBounds = includes(b, bounds) ? b : bounds
134
+ if (contentBounds !== layout.contentBounds) {
135
+ layout.contentBounds = contentBounds
136
+ layout.renderBoundsChanged = true
137
+ }
138
+
139
+ }
140
+
141
+ public __updateRenderBoundsSpreadWidth(): number {
142
+ let width = super.__updateRenderBoundsSpreadWidth()
143
+ if (!width) width = this.__layout.boxBounds === this.__layout.contentBounds ? 0 : 1
144
+ return width
145
+ }
94
146
 
95
- b.x = width ? 0 : data.x || 0
96
- b.y = height ? 0 : data.y || 0
97
- b.width = width ? Math.max(width, data.width) : data.width
98
- b.height = height ? Math.max(height, data.height) : data.height
147
+ public __updateRenderBounds(): void {
148
+ copyAndSpread(this.__layout.renderBounds, this.__layout.contentBounds, this.__layout.renderBoundsSpreadWidth)
99
149
  }
100
150
 
101
151
  }
package/src/UI.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ILeaferCanvas, IPathDrawer, IPathCommandData, IHitType, __Number, __Boolean, __String } from '@leafer/interface'
2
- import { Leaf, PathHelper, affectEventBoundsType, surfaceType, dataType, positionType, boundsType, pathType, scaleType, rotationType, opacityType, sortType, maskType, dataProcessor, useModule, rewrite, rewriteAble, UICreator } from '@leafer/core'
2
+ import { Leaf, PathDrawer, surfaceType, dataType, positionType, boundsType, pathType, scaleType, rotationType, opacityType, sortType, maskType, dataProcessor, useModule, rewrite, rewriteAble, UICreator, PathCorner, hitType, strokeType } from '@leafer/core'
3
3
 
4
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'
@@ -16,7 +16,6 @@ import { Paint } from '@leafer-ui/external'
16
16
  @rewriteAble()
17
17
  export class UI extends Leaf implements IUI {
18
18
 
19
-
20
19
  @dataProcessor(UIData)
21
20
  public __: IUIData
22
21
 
@@ -94,15 +93,21 @@ export class UI extends Leaf implements IUI {
94
93
  public draggable: __Boolean
95
94
 
96
95
  // hit
97
- @dataType(true)
96
+ @hitType(true)
98
97
  public hittable: __Boolean
99
98
 
100
- @dataType('visible')
101
- public hitType: IHitType
99
+ @hitType('visible')
100
+ public hitFill: IHitType
101
+
102
+ @strokeType('visible')
103
+ public hitStroke: IHitType
102
104
 
103
- @dataType(true)
105
+ @hitType(true)
104
106
  public hitChildren: __Boolean
105
107
 
108
+ @hitType(true)
109
+ public hitSelf: __Boolean
110
+
106
111
  // ---
107
112
 
108
113
 
@@ -113,28 +118,28 @@ export class UI extends Leaf implements IUI {
113
118
 
114
119
  // stroke
115
120
 
116
- @affectEventBoundsType()
121
+ @strokeType()
117
122
  public stroke: IPaint | IPaint[] | IPaintString
118
123
 
119
- @affectEventBoundsType('inside')
124
+ @strokeType('inside')
120
125
  public strokeAlign: IStrokeAlign
121
126
 
122
- @affectEventBoundsType(1)
127
+ @strokeType(1)
123
128
  public strokeWidth: number | number[] | IStrokeWidthString
124
129
 
125
- @surfaceType('none')
130
+ @strokeType('none')
126
131
  public strokeCap: IStrokeCap
127
132
 
128
- @surfaceType('miter')
133
+ @strokeType('miter')
129
134
  public strokeJoin: IStrokeJoin
130
135
 
131
- @surfaceType()
136
+ @strokeType()
132
137
  public dashPattern: __Number[] | IDashPatternString
133
138
 
134
- @surfaceType()
139
+ @strokeType()
135
140
  public dashOffset: __Number
136
141
 
137
- @surfaceType(10)
142
+ @strokeType(10)
138
143
  public miterLimit: __Number
139
144
 
140
145
 
@@ -188,7 +193,7 @@ export class UI extends Leaf implements IUI {
188
193
  public __updateRenderPath(): void {
189
194
  if (this.__.path) {
190
195
  const { __: data } = this
191
- data.__pathForRender = data.cornerRadius ? PathHelper.smoothCorner(data.path, data.cornerRadius, data.cornerSmoothing) : data.path
196
+ data.__pathForRender = data.cornerRadius ? PathCorner.smooth(data.path, data.cornerRadius, data.cornerSmoothing) : data.path
192
197
  }
193
198
  }
194
199
 
@@ -202,7 +207,7 @@ export class UI extends Leaf implements IUI {
202
207
  this.__drawPathByData(canvas, this.__.path)
203
208
  }
204
209
 
205
- @rewrite(PathHelper.drawData)
210
+ @rewrite(PathDrawer.drawPathByData)
206
211
  public __drawPathByData(_drawer: IPathDrawer, _data: IPathCommandData): void { }
207
212
 
208
213
  static one(data: IUITagInputData, x?: number, y?: number, width?: number, height?: number): IUI {
package/src/index.ts CHANGED
@@ -1,13 +1,23 @@
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'
12
+
13
+ export { Image } from './Image'
14
+ export { Canvas } from './Canvas'
15
+
16
+ export { Text } from './Text'
17
+
9
18
  export { Path } from './Path'
19
+ export { Pen } from './Pen'
10
20
  export { Vector } from './Vector'
11
- export { Text } from './Text'
12
- export { Image } from './Image'
21
+
22
+
13
23