@leafer/display 1.0.0-alpha.21 → 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.
Files changed (3) hide show
  1. package/package.json +9 -9
  2. package/src/Branch.ts +86 -37
  3. package/src/Leaf.ts +121 -56
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leafer/display",
3
- "version": "1.0.0-alpha.21",
3
+ "version": "1.0.0-alpha.30",
4
4
  "description": "@leafer/display",
5
5
  "author": "Chao (Leafer) Wan",
6
6
  "license": "MIT",
@@ -19,15 +19,15 @@
19
19
  "leaferjs"
20
20
  ],
21
21
  "dependencies": {
22
- "@leafer/math": "1.0.0-alpha.21",
23
- "@leafer/data": "1.0.0-alpha.21",
24
- "@leafer/layout": "1.0.0-alpha.21",
25
- "@leafer/display-module": "1.0.0-alpha.21",
26
- "@leafer/event": "1.0.0-alpha.21",
27
- "@leafer/decorator": "1.0.0-alpha.21",
28
- "@leafer/helper": "1.0.0-alpha.21"
22
+ "@leafer/math": "1.0.0-alpha.30",
23
+ "@leafer/data": "1.0.0-alpha.30",
24
+ "@leafer/layout": "1.0.0-alpha.30",
25
+ "@leafer/display-module": "1.0.0-alpha.30",
26
+ "@leafer/event": "1.0.0-alpha.30",
27
+ "@leafer/decorator": "1.0.0-alpha.30",
28
+ "@leafer/helper": "1.0.0-alpha.30"
29
29
  },
30
30
  "devDependencies": {
31
- "@leafer/interface": "1.0.0-alpha.21"
31
+ "@leafer/interface": "1.0.0-alpha.30"
32
32
  }
33
33
  }
package/src/Branch.ts CHANGED
@@ -1,29 +1,32 @@
1
1
  import { ILeaf, ILeaferCanvas, IRenderOptions } from '@leafer/interface'
2
2
  import { ChildEvent } from '@leafer/event'
3
3
  import { BoundsHelper } from '@leafer/math'
4
- import { BranchHelper, LeafBoundsHelper } from '@leafer/helper'
4
+ import { BranchHelper, LeafBoundsHelper, WaitHelper } from '@leafer/helper'
5
+ import { useModule } from '@leafer/decorator'
6
+ import { LeafMask } from '@leafer/display-module'
5
7
 
6
8
  import { Leaf } from './Leaf'
7
9
 
8
10
 
9
11
  const { setByListWithHandle } = BoundsHelper
10
12
  const { sort } = BranchHelper
11
- const { relativeBoxBounds: localBoxBounds, relativeEventBounds: localEventBounds, relativeRenderBounds: localRenderBounds } = LeafBoundsHelper
13
+ const { localBoxBounds, localEventBounds, localRenderBounds, maskLocalBoxBounds, maskLocalEventBounds, maskLocalRenderBounds } = LeafBoundsHelper
12
14
 
15
+ @useModule(LeafMask)
13
16
  export class Branch extends Leaf {
14
17
 
15
18
  constructor() {
16
19
  super()
17
- this.__isBranch = true
20
+ this.isBranch = true
18
21
  this.children = []
19
22
  }
20
23
 
21
24
  // overwrite
22
25
 
23
- public __updateEventBoundsSpreadWidth(): number {
26
+ public __updateStrokeBoundsSpreadWidth(): number {
24
27
  const { children } = this
25
28
  for (let i = 0, len = children.length; i < len; i++) {
26
- if (children[i].__layout.eventBoundsSpreadWidth) return 1
29
+ if (children[i].__layout.strokeBoundsSpreadWidth) return 1
27
30
  }
28
31
  return 0
29
32
  }
@@ -36,17 +39,16 @@ export class Branch extends Leaf {
36
39
  return 0
37
40
  }
38
41
 
39
-
40
42
  public __updateBoxBounds(): void {
41
- setByListWithHandle(this.__layout.boxBounds, this.children, localBoxBounds)
43
+ setByListWithHandle(this.__layout.boxBounds, this.children, this.__hasMask ? maskLocalBoxBounds : localBoxBounds)
42
44
  }
43
45
 
44
- public __updateEventBounds(): void {
45
- setByListWithHandle(this.__layout.eventBounds, this.children, localEventBounds)
46
+ public __updateStrokeBounds(): void {
47
+ setByListWithHandle(this.__layout.strokeBounds, this.children, this.__hasMask ? maskLocalEventBounds : localEventBounds)
46
48
  }
47
49
 
48
50
  public __updateRenderBounds(): void {
49
- setByListWithHandle(this.__layout.renderBounds, this.children, localRenderBounds)
51
+ setByListWithHandle(this.__layout.renderBounds, this.children, this.__hasMask ? maskLocalRenderBounds : localRenderBounds)
50
52
  }
51
53
 
52
54
  public __updateChange(): void {
@@ -73,13 +75,52 @@ export class Branch extends Leaf {
73
75
  public __render(canvas: ILeaferCanvas, options: IRenderOptions): void {
74
76
 
75
77
  if (this.__worldOpacity) {
78
+
76
79
  let child: ILeaf
77
- const { bounds, hideBounds } = options, { children } = this
78
- for (let i = 0, len = children.length; i < len; i++) {
79
- child = children[i]
80
- if (bounds && !bounds.hit(child.__world, options.matrix)) continue
81
- if (hideBounds && hideBounds.includes(child.__world)) continue
82
- child.__render(canvas, options)
80
+ const { children } = this
81
+
82
+ if (this.__hasMask && children.length > 1) {
83
+
84
+ let mask: boolean
85
+ let maskCanvas = canvas.getSameCanvas()
86
+ let contentCanvas = canvas.getSameCanvas()
87
+
88
+ for (let i = 0, len = children.length; i < len; i++) {
89
+ child = children[i]
90
+
91
+ if (child.isMask) {
92
+ if (mask) {
93
+ this.__renderMask(canvas, contentCanvas, maskCanvas)
94
+ maskCanvas.clear()
95
+ contentCanvas.clear()
96
+ } else {
97
+ mask = true
98
+ }
99
+
100
+ child.__render(maskCanvas, options)
101
+ continue
102
+ }
103
+
104
+ child.__render(contentCanvas, options)
105
+ }
106
+
107
+ this.__renderMask(canvas, contentCanvas, maskCanvas)
108
+ maskCanvas.recycle()
109
+ contentCanvas.recycle()
110
+
111
+ } else {
112
+
113
+ const { bounds, hideBounds } = options
114
+
115
+ for (let i = 0, len = children.length; i < len; i++) {
116
+ child = children[i]
117
+
118
+ if (bounds && !bounds.hit(child.__world, options.matrix)) continue
119
+ if (hideBounds && hideBounds.includes(child.__world, options.matrix)) continue
120
+
121
+ child.__render(canvas, options)
122
+ }
123
+
83
124
  }
84
125
  }
85
126
 
@@ -87,25 +128,27 @@ export class Branch extends Leaf {
87
128
 
88
129
  public add(child: ILeaf, index?: number): void {
89
130
 
90
- if (child.parent) {
91
- if (child.parent !== this) console.warn('child had other parent, can not add to this, child innerId:' + child.innerId)
92
- return
93
- }
94
-
131
+ if (child.parent) child.parent.remove(child)
95
132
  child.parent = this
96
133
 
97
134
  index === undefined ? this.children.push(child) : this.children.splice(index, 0, child)
98
- if (child.__isBranch) this.__.__childBranchNumber ? this.__.__childBranchNumber++ : this.__.__childBranchNumber = 1
135
+ if (child.isBranch) this.__.__childBranchNumber = (this.__.__childBranchNumber || 0) + 1
136
+ child.__layout.boundsChanged || child.__layout.positionChange() // layouted(removed), need update
137
+
138
+ if (child.__parentWait) WaitHelper.run(child.__parentWait)
99
139
 
100
- if (this.root) {
101
- child.__bindRoot(this.root)
140
+ if (this.leafer) {
141
+ child.__bindLeafer(this.leafer)
102
142
 
103
- const event = new ChildEvent(ChildEvent.ADD, child, this)
104
- if (this.hasEvent(ChildEvent.ADD)) this.emitEvent(event)
105
- this.root.emitEvent(event)
143
+ if (this.leafer.ready) {
144
+ const { ADD } = ChildEvent
145
+ const event = new ChildEvent(ADD, child, this)
146
+ if (child.hasEvent(ADD)) child.emitEvent(event)
147
+ if (this.hasEvent(ADD) && !this.isLeafer) this.emitEvent(event)
148
+ this.leafer.emitEvent(event)
149
+ }
106
150
  }
107
151
 
108
- if (child.__parentWait) child.__runParentWait()
109
152
  }
110
153
 
111
154
  public remove(child?: Leaf): void {
@@ -114,21 +157,27 @@ export class Branch extends Leaf {
114
157
  const index = this.children.indexOf(child)
115
158
  if (index > -1) {
116
159
  this.children.splice(index, 1)
160
+ if (this.__hasMask) this.__updateMask()
161
+ this.__layout.boxBoundsChange()
162
+
163
+ if (child.isBranch) this.__.__childBranchNumber = (this.__.__childBranchNumber || 1) - 1
164
+ child.parent = null
117
165
 
118
- if (child.__isBranch) this.__.__childBranchNumber > 1 ? this.__.__childBranchNumber-- : this.__.__childBranchNumber = 0
166
+ if (this.leafer) {
167
+ child.__bindLeafer(null)
119
168
 
120
- if (this.root) {
121
- const event = new ChildEvent(ChildEvent.REMOVE, child, this)
122
- if (this.hasEvent(ChildEvent.REMOVE)) this.emitEvent(event)
123
- this.root.emitEvent(event)
124
- child.root = null
169
+ if (this.leafer.ready) {
170
+ const { REMOVE } = ChildEvent
171
+ const event = new ChildEvent(REMOVE, child, this)
172
+ if (child.hasEvent(REMOVE)) child.emitEvent(event)
173
+ if (this.hasEvent(REMOVE) && !this.isLeafer) this.emitEvent(event)
174
+ this.leafer.emitEvent(event)
175
+ }
125
176
  }
126
177
 
127
- child.parent = null
128
- this.__layout.boxBoundsChange()
129
178
  }
130
179
  } else {
131
- if (this.parent) this.parent.remove(this)
180
+ super.remove()
132
181
  }
133
182
 
134
183
  }
package/src/Leaf.ts CHANGED
@@ -1,9 +1,10 @@
1
- import { ILeafer, ILeaf, ILeafInputData, ILeafData, ILeaferCanvas, IRenderOptions, IMatrixWithBoundsData, __Number, __Boolean, ILeafLayout, InnerId, IHitCanvas, IRadiusPointData, IEventListenerMap, IEventListener, IEventListenerOptions, IEventListenerId, IEvent, IObject, IFunction, __String } from '@leafer/interface'
2
- import { IncrementId } from '@leafer/math'
1
+ import { ILeafer, ILeaf, ILeafInputData, ILeafData, ILeaferCanvas, IRenderOptions, IMatrixWithBoundsData, __Number, __Boolean, __Value, ILeafLayout, InnerId, IHitCanvas, IRadiusPointData, IEventListenerMap, IEventListener, IEventListenerOptions, IEventListenerId, IEvent, IObject, IFunction, __String, IPointData, IMatrixDecompositionAttr, ILayoutBoundsType, ILayoutLocationType, IBoundsData, IMatrixData } from '@leafer/interface'
2
+ import { IncrementId, MatrixHelper, PointHelper } from '@leafer/math'
3
3
  import { LeafData } from '@leafer/data'
4
4
  import { LeafLayout } from '@leafer/layout'
5
5
  import { LeafDataProxy, LeafMatrix, LeafBounds, LeafHit, LeafEventer, LeafRender } from '@leafer/display-module'
6
6
  import { useModule } from '@leafer/decorator'
7
+ import { WaitHelper } from '@leafer/helper'
7
8
 
8
9
 
9
10
  const { LEAF, create } = IncrementId
@@ -16,39 +17,56 @@ const { LEAF, create } = IncrementId
16
17
  @useModule(LeafRender)
17
18
  export class Leaf implements ILeaf {
18
19
 
19
- public get tag(): string { return this.constructor.name }
20
+ public get tag(): string { return this.__tag }
21
+ public get __tag(): string { return 'Leaf' }
22
+
20
23
  public readonly innerId: InnerId // 内部唯一标识
24
+ public get innerName(): string { return this.__.name || this.tag + this.innerId }
25
+
21
26
  public get __DataProcessor() { return LeafData }
22
27
  public get __LayoutProcessor() { return LeafLayout }
23
28
 
24
29
  public leafer?: ILeafer
25
- public root?: ILeaf
26
30
  public parent?: ILeaf
27
31
 
28
- public __isRoot: boolean
29
- public __isBranch: boolean
30
- public __isBranchLeaf: boolean
32
+ public isLeafer: boolean
33
+ public isBranch: boolean
34
+ public isBranchLeaf: boolean
31
35
 
32
36
  public __: ILeafData
33
37
  public __layout: ILeafLayout
34
38
 
35
- public __relative: IMatrixWithBoundsData
39
+ public __local: IMatrixWithBoundsData
36
40
  public __world: IMatrixWithBoundsData
37
-
38
41
  public __worldOpacity: number
39
- public __renderTime: number // μs 1000微秒 = 1毫秒
40
42
 
41
- public __level: number // 所在层级 0 -> 高
42
- public __tempNumber: number // 用于排序,记录最后一次在parent中的排序索引,可用于移除之后回退
43
+ // now transform
44
+ public get worldTransform(): IMatrixData { return this.__layout.getTransform('world') }
45
+ public get localTransform(): IMatrixData { return this.__layout.getTransform('local') }
46
+
47
+ // now bounds
48
+ public get worldBoxBounds(): IBoundsData { return this.getBounds('box') }
49
+ public get worldStrokeBounds(): IBoundsData { return this.getBounds('stroke') }
50
+ public get worldRenderBounds(): IBoundsData { return this.getBounds('render') }
43
51
 
52
+ // now opacity
53
+ public get worldOpacity(): number { this.__layout.checkUpdate(); return this.__worldOpacity }
54
+
55
+ public __level: number // layer level 0 -> branch -> branch -> deep
56
+ public __tempNumber: number // temp sort
57
+
58
+ public __hasMask?: boolean
44
59
  public __hitCanvas?: IHitCanvas
45
60
 
61
+ public get __onlyHitMask(): boolean { return this.__hasMask && !this.__.hitChildren }
62
+ public get __ignoreHitWorld(): boolean { return this.__hasMask && this.__.hitChildren }
63
+
46
64
  // event
47
65
  public __captureMap?: IEventListenerMap
48
66
  public __bubbleMap?: IEventListenerMap
49
67
 
50
68
  public __parentWait?: IFunction[]
51
-
69
+ public __leaferWait?: IFunction[]
52
70
 
53
71
  // branch
54
72
  public children?: ILeaf[]
@@ -57,11 +75,10 @@ export class Leaf implements ILeaf {
57
75
 
58
76
  this.innerId = create(LEAF)
59
77
 
60
- this.__relative = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0, x: 0, y: 0, width: 0, height: 0 }
78
+ this.__local = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0, x: 0, y: 0, width: 0, height: 0 }
61
79
  this.__world = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0, x: 0, y: 0, width: 0, height: 0 }
62
80
 
63
81
  this.__worldOpacity = 1
64
- this.__renderTime = 2
65
82
 
66
83
  this.__ = new this.__DataProcessor(this)
67
84
  this.__layout = new this.__LayoutProcessor(this)
@@ -70,99 +87,144 @@ export class Leaf implements ILeaf {
70
87
  }
71
88
 
72
89
 
73
- public __addParentWait(item: IFunction): void {
90
+ public waitParent(item: IFunction): void {
74
91
  this.__parentWait ? this.__parentWait.push(item) : this.__parentWait = [item]
75
92
  }
76
93
 
77
- public __runParentWait(): void {
78
- const len = this.__parentWait.length
79
- for (let i = 0; i < len; i++) {
80
- this.__parentWait[i]()
81
- }
82
- this.__parentWait = null
94
+ public waitLeafer(item: IFunction): void {
95
+ this.__leaferWait ? this.__leaferWait.push(item) : this.__leaferWait = [item]
83
96
  }
84
97
 
85
- public __setAsLeafer(): void {
86
- this.leafer = this as unknown as ILeafer
87
- }
88
98
 
89
- public __setAsRoot(): void {
90
- this.__bindRoot(this)
91
- this.__isRoot = true
92
- }
99
+ public __bindLeafer(leafer: ILeafer | null): void {
100
+ if (this.isLeafer) leafer = this as unknown as ILeafer
93
101
 
94
- public __bindRoot(root: ILeaf): void {
95
- if (this.__isRoot) return
96
-
97
- this.root = root
98
- this.leafer = root.leafer
102
+ this.leafer = leafer
99
103
  this.__level = this.parent ? this.parent.__level + 1 : 1
100
104
 
101
- if (this.__isBranch) {
105
+ if (this.__leaferWait && leafer) WaitHelper.run(this.__leaferWait)
106
+
107
+ if (this.isBranch) {
102
108
  const { children } = this
103
109
  for (let i = 0, len = children.length; i < len; i++) {
104
- children[i].__bindRoot(root)
110
+ children[i].__bindLeafer(leafer)
105
111
  }
106
112
  }
107
113
  }
108
114
 
115
+ public set(_data: IObject): void { }
109
116
 
110
- // LeafDataProxy rewrite
117
+ public get(_attrNames?: string[]): IObject { return undefined }
111
118
 
112
- public __set(_attrName: string, _newValue: unknown): void { }
113
119
 
114
- public __get(_attrName: string): unknown { return undefined }
120
+ // LeafDataProxy rewrite
121
+
122
+ public __setAttr(_attrName: string, _newValue: __Value): void { }
115
123
 
116
- public __updateAttr(_attrName: string): void { }
124
+ public __getAttr(_attrName: string): __Value { return undefined }
117
125
 
118
126
  // ---
119
127
 
128
+ public forceUpdate(attrName?: string): void {
129
+ if (!attrName) attrName = 'x'
130
+ const value = this.__.__get(attrName)
131
+ this.__[attrName] = (value === null) ? 0 : null;
132
+ (this as any)[attrName] = value
133
+ }
134
+
120
135
 
121
136
  // LeafMatrix rewrite
122
137
 
123
138
  public __updateWorldMatrix(): void { }
124
139
 
125
- public __updateRelativeMatrix(): void { }
140
+ public __updateLocalMatrix(): void { }
126
141
 
127
142
  // ---
128
143
 
129
-
130
144
  // LeafBounds rewrite
131
145
 
132
146
  public __updateWorldBounds(): void { }
133
147
 
134
148
 
135
- public __updateRelativeBoxBounds(): void { }
149
+ public __updateLocalBoxBounds(): void { }
136
150
 
137
- public __updateRelativeEventBounds(): void { }
151
+ public __updateLocalStrokeBounds(): void { }
138
152
 
139
- public __updateRelativeRenderBounds(): void { }
153
+ public __updateLocalRenderBounds(): void { }
140
154
 
141
155
  // box
142
156
 
143
157
  public __updateBoxBounds(): void { }
144
158
 
145
- public __updateEventBounds(): void { }
159
+ public __updateStrokeBounds(): void { }
146
160
 
147
161
  public __updateRenderBounds(): void { }
148
162
 
149
163
 
150
- public __updateEventBoundsSpreadWidth(): number { return 0 }
164
+ public __updateStrokeBoundsSpreadWidth(): number { return 0 }
151
165
 
152
166
  public __updateRenderBoundsSpreadWidth(): number { return 0 }
153
167
 
154
-
155
168
  public __onUpdateSize(): void { }
156
169
 
157
170
  // ---
158
171
 
159
172
 
173
+ // LeafMask rewrite
174
+
175
+ public __updateMask(): void { }
176
+
177
+ public __renderMask(_canvas: ILeaferCanvas, _content: ILeaferCanvas, _mask: ILeaferCanvas): void { }
178
+
179
+ public __removeMask(_child?: ILeaf): void { }
180
+
181
+ // ---
182
+
183
+
184
+ // convert
185
+
186
+ public getWorld(attrName: IMatrixDecompositionAttr): number {
187
+ return this.__layout.getMatrixDecompositionData('world')[attrName]
188
+ }
189
+
190
+ public getBounds(type: ILayoutBoundsType, locationType: ILayoutLocationType = 'world'): IBoundsData {
191
+ return this.__layout.getBounds(type, locationType)
192
+ }
193
+
194
+
195
+ public worldToLocal(world: IPointData, to?: IPointData, isMovePoint?: boolean): void {
196
+ if (this.parent) {
197
+ MatrixHelper.toInnerPoint(this.parent.worldTransform, world, to, isMovePoint)
198
+ } else {
199
+ if (to) PointHelper.copy(to, world)
200
+ }
201
+ }
202
+
203
+ public localToWorld(local: IPointData, to?: IPointData, isMovePoint?: boolean): void {
204
+ if (this.parent) {
205
+ MatrixHelper.toOuterPoint(this.parent.worldTransform, local, to, isMovePoint)
206
+ } else {
207
+ if (to) PointHelper.copy(to, local)
208
+ }
209
+ }
210
+
211
+ public worldToInner(world: IPointData, to?: IPointData, isMovePoint?: boolean): void {
212
+ MatrixHelper.toInnerPoint(this.worldTransform, world, to, isMovePoint)
213
+ }
214
+
215
+ public innerToWorld(inner: IPointData, to?: IPointData, isMovePoint?: boolean): void {
216
+ MatrixHelper.toOuterPoint(this.worldTransform, inner, to, isMovePoint)
217
+ }
218
+
219
+
160
220
  // LeafHit rewrite
161
221
 
162
222
  public __hitWorld(_point: IRadiusPointData): boolean { return true }
163
223
 
164
224
  public __hit(_local: IRadiusPointData): boolean { return true }
165
225
 
226
+ public __drawHitPath(_canvas: ILeaferCanvas): void { }
227
+
166
228
  public __updateHitCanvas(): void { }
167
229
 
168
230
  // ---
@@ -176,6 +238,9 @@ export class Leaf implements ILeaf {
176
238
 
177
239
  public __draw(_canvas: ILeaferCanvas, _options: IRenderOptions): void { }
178
240
 
241
+ public __renderShape(_canvas: ILeaferCanvas, _options: IRenderOptions): void { }
242
+
243
+
179
244
  public __updateWorldOpacity(): void { }
180
245
 
181
246
  public __updateRenderTime(): void { }
@@ -202,7 +267,9 @@ export class Leaf implements ILeaf {
202
267
 
203
268
  public add(_child: ILeaf, _index?: number): void { }
204
269
 
205
- public remove(_child?: ILeaf): void { }
270
+ public remove(_child?: ILeaf): void {
271
+ if (this.parent) this.parent.remove(this)
272
+ }
206
273
 
207
274
  // ---
208
275
 
@@ -229,19 +296,12 @@ export class Leaf implements ILeaf {
229
296
 
230
297
  public destroy(): void {
231
298
  if (this.__) {
232
-
233
- if (this.__isBranch) {
234
- this.children.forEach(child => { child.destroy() })
235
- this.children = null
236
- }
237
-
238
299
  if (this.__hitCanvas) {
239
300
  this.__hitCanvas.destroy()
240
301
  this.__hitCanvas = null
241
302
  }
242
303
 
243
304
  this.leafer = null
244
- this.root = null
245
305
  this.parent = null
246
306
 
247
307
  this.__.destroy()
@@ -251,6 +311,11 @@ export class Leaf implements ILeaf {
251
311
 
252
312
  this.__captureMap = null
253
313
  this.__bubbleMap = null
314
+
315
+ if (this.children) {
316
+ this.children.forEach(child => { child.destroy() })
317
+ this.children.length = 0
318
+ }
254
319
  }
255
320
  }
256
321