@leafer/renderer 1.0.0-alpha.21 → 1.0.0-alpha.23

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/renderer",
3
- "version": "1.0.0-alpha.21",
3
+ "version": "1.0.0-alpha.23",
4
4
  "description": "@leafer/renderer",
5
5
  "author": "Chao (Leafer) Wan",
6
6
  "license": "MIT",
@@ -19,13 +19,13 @@
19
19
  "leaferjs"
20
20
  ],
21
21
  "dependencies": {
22
- "@leafer/event": "1.0.0-alpha.21",
23
- "@leafer/math": "1.0.0-alpha.21",
24
- "@leafer/data": "1.0.0-alpha.21",
25
- "@leafer/platform": "1.0.0-alpha.21",
26
- "@leafer/debug": "1.0.0-alpha.21"
22
+ "@leafer/event": "1.0.0-alpha.23",
23
+ "@leafer/math": "1.0.0-alpha.23",
24
+ "@leafer/data": "1.0.0-alpha.23",
25
+ "@leafer/platform": "1.0.0-alpha.23",
26
+ "@leafer/debug": "1.0.0-alpha.23"
27
27
  },
28
28
  "devDependencies": {
29
- "@leafer/interface": "1.0.0-alpha.21"
29
+ "@leafer/interface": "1.0.0-alpha.23"
30
30
  }
31
31
  }
package/src/Renderer.ts CHANGED
@@ -1,10 +1,12 @@
1
- import { ILeaf, ILeaferCanvas, IRenderer, IRendererConfig, IEventListenerId, IBounds, IFunction } from '@leafer/interface'
1
+ import { ILeaf, ILeaferCanvas, IRenderer, IRendererConfig, IEventListenerId, IBounds, IFunction, IRenderOptions } from '@leafer/interface'
2
2
  import { LayoutEvent, RenderEvent, ResizeEvent } from '@leafer/event'
3
3
  import { Bounds } from '@leafer/math'
4
4
  import { DataHelper } from '@leafer/data'
5
5
  import { Platform } from '@leafer/platform'
6
6
  import { Debug, Run } from '@leafer/debug'
7
7
 
8
+ import { renderHitView } from './renderHitView'
9
+
8
10
 
9
11
  const debug = Debug.get('Renderer')
10
12
 
@@ -28,7 +30,7 @@ export class Renderer implements IRenderer {
28
30
 
29
31
  protected __eventIds: IEventListenerId[]
30
32
 
31
- constructor(target: ILeaf, canvas: ILeaferCanvas, userConfig: IRendererConfig) {
33
+ constructor(target: ILeaf, canvas: ILeaferCanvas, userConfig?: IRendererConfig) {
32
34
  this.target = target
33
35
  this.canvas = canvas
34
36
  if (userConfig) this.config = DataHelper.default(userConfig, this.config)
@@ -60,7 +62,6 @@ export class Renderer implements IRenderer {
60
62
 
61
63
  target.emit(RenderEvent.START)
62
64
  this.renderOnce(callback)
63
- target.emit(RenderEvent.RENDER)
64
65
  target.emit(RenderEvent.END)
65
66
 
66
67
  debug.log(target.innerId, '---|')
@@ -75,7 +76,7 @@ export class Renderer implements IRenderer {
75
76
 
76
77
  if (callback) {
77
78
 
78
- target.emit(RenderEvent.BEFORE_ONCE)
79
+ target.emit(RenderEvent.BEFORE)
79
80
 
80
81
  callback()
81
82
 
@@ -83,7 +84,7 @@ export class Renderer implements IRenderer {
83
84
 
84
85
  this.requestLayout()
85
86
 
86
- target.emit(RenderEvent.BEFORE_ONCE)
87
+ target.emit(RenderEvent.BEFORE)
87
88
 
88
89
  if (this.config.usePartRender && this.totalTimes > 1) {
89
90
  this.partRender()
@@ -93,9 +94,8 @@ export class Renderer implements IRenderer {
93
94
 
94
95
  }
95
96
 
96
- target.emit(RenderEvent.ONCE)
97
- target.emit(RenderEvent.AFTER_ONCE)
98
-
97
+ target.emit(RenderEvent.RENDER)
98
+ target.emit(RenderEvent.AFTER)
99
99
 
100
100
  this.updateBlocks = null
101
101
 
@@ -104,73 +104,69 @@ export class Renderer implements IRenderer {
104
104
 
105
105
  public partRender(): void {
106
106
  const { canvas, updateBlocks: list } = this
107
+ if (!list) return debug.warn('PartRender: need update attr')
107
108
 
108
- if (!list) {
109
- debug.warn('PartRender: layoutedBlocks is empty')
110
- this.fullRender(canvas.bounds)
111
- return
112
- }
113
-
114
- if (list.some(block => block.includes(this.target.__world))) {
115
- this.mergeBlocks()
116
- this.clipRender(this.updateBlocks[0], true)
117
- } else {
118
- list.forEach(block => {
119
- if (canvas.bounds.hit(block) && !block.isEmpty()) this.clipRender(block.getIntersect(canvas.bounds))
120
- })
121
- }
109
+ if (list.some(block => block.includes(this.target.__world))) this.mergeBlocks()
110
+ list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty()) this.clipRender(block) })
122
111
  }
123
112
 
124
- public clipRender(bounds: IBounds, fullMode?: boolean): void {
113
+ public clipRender(block: IBounds): void {
125
114
  const t = Run.start('PartRender')
126
- const { canvas, target } = this
115
+ const { canvas } = this
127
116
 
128
- bounds.spread(1 + 1 / this.canvas.pixelRatio)
129
- bounds.ceil()
117
+ const bounds = block.getIntersect(canvas.bounds)
118
+ const includes = block.includes(this.target.__world)
130
119
 
131
120
  canvas.save()
132
- canvas.clearWorld(bounds, true)
133
- if (Debug.showRepaint) canvas.strokeWorld(bounds, 'red')
134
- canvas.clipWorld(bounds, true)
135
- target.__render(canvas, fullMode ? {} : { bounds })
121
+ if (Debug.showRepaint || !includes) {
122
+ bounds.spread(1 + 1 / this.canvas.pixelRatio).ceil()
123
+ canvas.clearWorld(bounds, true)
124
+ canvas.clipWorld(bounds, true)
125
+ if (Debug.showRepaint) canvas.strokeWorld(bounds, 'red')
126
+ } else {
127
+ canvas.clear()
128
+ }
129
+ this.__render(bounds)
136
130
  canvas.restore()
137
131
 
138
132
  Run.end(t)
139
133
  }
140
134
 
141
- public fullRender(bounds?: IBounds): void {
142
- const { canvas, target } = this
143
- Renderer.fullRender(target, canvas, bounds)
144
- }
145
-
146
- static fullRender(target: ILeaf, canvas: ILeaferCanvas, bounds?: IBounds): void {
135
+ public fullRender(): void {
147
136
  const t = Run.start('FullRender')
148
- if (!bounds) bounds = canvas.bounds
137
+ const { canvas } = this
149
138
 
150
139
  canvas.save()
151
140
  canvas.clear()
152
- target.__render(canvas, canvas.bounds.includes(target.__world) ? {} : { bounds })
141
+ this.__render(canvas.bounds)
153
142
  canvas.restore()
154
143
 
155
144
  Run.end(t)
156
145
  }
157
146
 
147
+ protected __render(bounds: IBounds): void {
148
+ const options: IRenderOptions = bounds?.includes(this.target.__world) ? {} : { bounds }
149
+ this.target.__render(this.canvas, options)
150
+ if (Debug.showHitView) renderHitView(this.target, this.canvas, options)
151
+ }
152
+
158
153
  public addBlock(block: IBounds): void {
159
154
  if (!this.updateBlocks) this.updateBlocks = []
160
155
  this.updateBlocks.push(block)
161
156
  }
162
157
 
163
158
  public mergeBlocks(): void {
164
- const { updateBlocks } = this
165
- if (updateBlocks) {
159
+ const { updateBlocks: list } = this
160
+ if (list) {
166
161
  const bounds = new Bounds()
167
- bounds.setByList(updateBlocks)
168
- this.updateBlocks = [bounds]
162
+ bounds.setByList(list)
163
+ list.length = 0
164
+ list.push(bounds)
169
165
  }
170
166
  }
171
167
 
172
168
  protected __checkAgain(): void {
173
- if (this.changed && this.times < 3) this.target.emit(RenderEvent.AGAIN)
169
+ //if (this.changed && this.times < 3) this.target.emit(RenderEvent.AGAIN)
174
170
  }
175
171
 
176
172
  protected __requestRender(): void {
@@ -195,7 +191,7 @@ export class Renderer implements IRenderer {
195
191
  }
196
192
 
197
193
  protected __onLayoutEnd(event: LayoutEvent): void {
198
- event.data.map(item => this.addBlock(item.updatedBounds))
194
+ event.data?.map(item => this.addBlock(item.updatedBounds))
199
195
  }
200
196
 
201
197
  protected __listenEvents(): void {
@@ -214,6 +210,7 @@ export class Renderer implements IRenderer {
214
210
 
215
211
  public destroy(): void {
216
212
  if (this.target) {
213
+ this.stop()
217
214
  this.__removeListenEvents()
218
215
  this.target = null
219
216
  this.canvas = null
@@ -0,0 +1,49 @@
1
+ import { ILeaf, ILeaferCanvas, IRenderOptions } from '@leafer/interface'
2
+
3
+
4
+ const colorList: string[] = []
5
+ for (let i = 0; i < 360; i++) {
6
+ colorList.push(Math.round(Math.random() * 360) + '')
7
+ }
8
+
9
+ export function renderHitView(target: ILeaf, canvas: ILeaferCanvas, options: IRenderOptions, hasMask?: boolean): void {
10
+ if (target.hittable) {
11
+ if (target.__isBranch) {
12
+ renderBranchHitView(target, canvas, options)
13
+ } else {
14
+ renderLeafHitView(target, canvas, options, hasMask)
15
+ }
16
+ }
17
+ }
18
+
19
+ export function renderBranchHitView(branch: ILeaf, canvas: ILeaferCanvas, options: IRenderOptions): void {
20
+ const { children } = branch
21
+ let target: ILeaf
22
+ for (let i = 0, len = children.length; i < len; i++) {
23
+ target = children[i]
24
+ if (target.hittable) {
25
+ if (target.__isBranch) {
26
+ renderBranchHitView(target, canvas, options)
27
+ } else {
28
+ renderLeafHitView(target, canvas, options, target.__hasMask)
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ function renderLeafHitView(leaf: ILeaf, canvas: ILeaferCanvas, options: IRenderOptions, hasMask: boolean): void {
35
+ if (leaf.__worldOpacity) {
36
+ const { isMask, __strokeOuterWidth: strokeWidth } = leaf.__
37
+ if (hasMask && !isMask) return
38
+
39
+ canvas.setWorld(leaf.__world, options.matrix)
40
+ canvas.opacity = 0.5
41
+
42
+ leaf.__drawHitPath(canvas)
43
+
44
+ canvas.fillStyle = canvas.strokeStyle = 'hsl(' + colorList[leaf.innerId % 360] + ',50%, 50%)'
45
+ canvas.fill(leaf.__.windingRule)
46
+ canvas.strokeWidth = strokeWidth ? strokeWidth * 2 : 1
47
+ canvas.stroke()
48
+ }
49
+ }