@leafer/renderer 1.0.0-alpha.10 → 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.10",
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.10",
23
- "@leafer/math": "1.0.0-alpha.10",
24
- "@leafer/data": "1.0.0-alpha.10",
25
- "@leafer/platform": "1.0.0-alpha.10",
26
- "@leafer/debug": "1.0.0-alpha.10"
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.10"
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,70 +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
116
+
117
+ const bounds = block.getIntersect(canvas.bounds)
118
+ const includes = block.includes(this.target.__world)
127
119
 
128
120
  canvas.save()
129
- canvas.clearBounds(bounds)
130
- if (Debug.showRepaint) canvas.strokeBounds(bounds, 'red')
131
- canvas.clipBounds(bounds)
132
- 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)
133
130
  canvas.restore()
134
131
 
135
132
  Run.end(t)
136
133
  }
137
134
 
138
- public fullRender(bounds?: IBounds): void {
139
- const { canvas, target } = this
140
- Renderer.fullRender(target, canvas, bounds)
141
- }
142
-
143
- static fullRender(target: ILeaf, canvas: ILeaferCanvas, bounds?: IBounds): void {
135
+ public fullRender(): void {
144
136
  const t = Run.start('FullRender')
145
- if (!bounds) bounds = canvas.bounds
137
+ const { canvas } = this
146
138
 
147
139
  canvas.save()
148
140
  canvas.clear()
149
- target.__render(canvas, canvas.bounds.includes(target.__world) ? {} : { bounds })
141
+ this.__render(canvas.bounds)
150
142
  canvas.restore()
151
143
 
152
144
  Run.end(t)
153
145
  }
154
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
+
155
153
  public addBlock(block: IBounds): void {
156
154
  if (!this.updateBlocks) this.updateBlocks = []
157
155
  this.updateBlocks.push(block)
158
156
  }
159
157
 
160
158
  public mergeBlocks(): void {
161
- const { updateBlocks } = this
162
- if (updateBlocks) {
159
+ const { updateBlocks: list } = this
160
+ if (list) {
163
161
  const bounds = new Bounds()
164
- bounds.setByList(updateBlocks)
165
- this.updateBlocks = [bounds]
162
+ bounds.setByList(list)
163
+ list.length = 0
164
+ list.push(bounds)
166
165
  }
167
166
  }
168
167
 
169
168
  protected __checkAgain(): void {
170
- if (this.changed && this.times < 3) this.target.emit(RenderEvent.AGAIN)
169
+ //if (this.changed && this.times < 3) this.target.emit(RenderEvent.AGAIN)
171
170
  }
172
171
 
173
172
  protected __requestRender(): void {
@@ -192,7 +191,7 @@ export class Renderer implements IRenderer {
192
191
  }
193
192
 
194
193
  protected __onLayoutEnd(event: LayoutEvent): void {
195
- event.data.map(item => this.addBlock(item.updatedBounds))
194
+ event.data?.map(item => this.addBlock(item.updatedBounds))
196
195
  }
197
196
 
198
197
  protected __listenEvents(): void {
@@ -211,6 +210,7 @@ export class Renderer implements IRenderer {
211
210
 
212
211
  public destroy(): void {
213
212
  if (this.target) {
213
+ this.stop()
214
214
  this.__removeListenEvents()
215
215
  this.target = null
216
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
+ }