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

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.23",
3
+ "version": "1.0.0-alpha.31",
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.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"
22
+ "@leafer/event": "1.0.0-alpha.31",
23
+ "@leafer/math": "1.0.0-alpha.31",
24
+ "@leafer/data": "1.0.0-alpha.31",
25
+ "@leafer/platform": "1.0.0-alpha.31",
26
+ "@leafer/debug": "1.0.0-alpha.31"
27
27
  },
28
28
  "devDependencies": {
29
- "@leafer/interface": "1.0.0-alpha.23"
29
+ "@leafer/interface": "1.0.0-alpha.31"
30
30
  }
31
31
  }
package/src/Renderer.ts CHANGED
@@ -5,8 +5,6 @@ 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
-
10
8
 
11
9
  const debug = Debug.get('Renderer')
12
10
 
@@ -21,6 +19,9 @@ export class Renderer implements IRenderer {
21
19
  public times: number = 0
22
20
 
23
21
  public running: boolean
22
+ public rendering: boolean
23
+
24
+ public waitAgain: boolean
24
25
  public changed: boolean
25
26
 
26
27
  public config: IRendererConfig = {
@@ -28,8 +29,14 @@ export class Renderer implements IRenderer {
28
29
  maxFPS: 60
29
30
  }
30
31
 
32
+ protected renderBounds: IBounds
33
+ protected renderOptions: IRenderOptions
34
+ protected totalBounds: IBounds
35
+
31
36
  protected __eventIds: IEventListenerId[]
32
37
 
38
+ protected get needFill(): boolean { return !!(!this.canvas.allowBackgroundColor && this.config.fill) }
39
+
33
40
  constructor(target: ILeaf, canvas: ILeaferCanvas, userConfig?: IRendererConfig) {
34
41
  this.target = target
35
42
  this.canvas = canvas
@@ -55,51 +62,70 @@ export class Renderer implements IRenderer {
55
62
  }
56
63
 
57
64
  public render(callback?: IFunction): void {
65
+ if (!(this.running)) return
66
+
58
67
  const { target } = this
59
68
  this.times = 0
69
+ this.totalBounds = new Bounds()
60
70
 
61
- debug.log(target.innerId, '--->')
71
+ debug.log(target.innerName, '--->')
62
72
 
63
- target.emit(RenderEvent.START)
64
- this.renderOnce(callback)
65
- target.emit(RenderEvent.END)
73
+ try {
74
+ this.emitRender(RenderEvent.START)
75
+ this.renderOnce(callback)
76
+ this.emitRender(RenderEvent.END, this.totalBounds)
77
+ } catch (e) {
78
+ debug.error(e)
79
+ }
80
+
81
+ debug.log('-------------|')
82
+ }
66
83
 
67
- debug.log(target.innerId, '---|')
84
+ public renderAgain(): void {
85
+ if (this.rendering) {
86
+ this.waitAgain = true
87
+ } else {
88
+ this.renderOnce()
89
+ }
68
90
  }
69
91
 
70
92
  public renderOnce(callback?: IFunction): void {
71
- const { target } = this
93
+ if (this.rendering) return debug.warn('rendering')
94
+ if (this.times > 3) return debug.warn('render max times')
72
95
 
73
96
  this.times++
74
97
  this.totalTimes++
98
+
99
+ this.rendering = true
75
100
  this.changed = false
101
+ this.renderBounds = new Bounds()
102
+ this.renderOptions = {}
76
103
 
77
104
  if (callback) {
78
-
79
- target.emit(RenderEvent.BEFORE)
80
-
105
+ this.emitRender(RenderEvent.BEFORE)
81
106
  callback()
82
-
83
107
  } else {
84
-
85
108
  this.requestLayout()
86
109
 
87
- target.emit(RenderEvent.BEFORE)
110
+ this.emitRender(RenderEvent.BEFORE)
88
111
 
89
112
  if (this.config.usePartRender && this.totalTimes > 1) {
90
113
  this.partRender()
91
114
  } else {
92
115
  this.fullRender()
93
116
  }
94
-
95
117
  }
96
118
 
97
- target.emit(RenderEvent.RENDER)
98
- target.emit(RenderEvent.AFTER)
119
+ this.emitRender(RenderEvent.RENDER, this.renderBounds, this.renderOptions)
120
+ this.emitRender(RenderEvent.AFTER, this.renderBounds, this.renderOptions)
99
121
 
100
122
  this.updateBlocks = null
123
+ this.rendering = false
101
124
 
102
- this.__checkAgain()
125
+ if (this.waitAgain) {
126
+ this.waitAgain = false
127
+ this.renderOnce()
128
+ }
103
129
  }
104
130
 
105
131
  public partRender(): void {
@@ -116,17 +142,19 @@ export class Renderer implements IRenderer {
116
142
 
117
143
  const bounds = block.getIntersect(canvas.bounds)
118
144
  const includes = block.includes(this.target.__world)
145
+ const realBounds = new Bounds().copy(bounds)
119
146
 
120
147
  canvas.save()
121
- if (Debug.showRepaint || !includes) {
148
+
149
+ if (includes && !Debug.showRepaint) {
150
+ canvas.clear()
151
+ } else {
122
152
  bounds.spread(1 + 1 / this.canvas.pixelRatio).ceil()
123
153
  canvas.clearWorld(bounds, true)
124
154
  canvas.clipWorld(bounds, true)
125
- if (Debug.showRepaint) canvas.strokeWorld(bounds, 'red')
126
- } else {
127
- canvas.clear()
128
155
  }
129
- this.__render(bounds)
156
+
157
+ this.__render(bounds, realBounds)
130
158
  canvas.restore()
131
159
 
132
160
  Run.end(t)
@@ -144,12 +172,26 @@ export class Renderer implements IRenderer {
144
172
  Run.end(t)
145
173
  }
146
174
 
147
- protected __render(bounds: IBounds): void {
175
+ protected __render(bounds: IBounds, realBounds?: IBounds): void {
148
176
  const options: IRenderOptions = bounds?.includes(this.target.__world) ? {} : { bounds }
177
+
178
+ if (this.needFill) this.canvas.fillWorld(bounds, this.config.fill)
179
+ if (Debug.showRepaint) this.canvas.strokeWorld(bounds, 'red')
180
+
149
181
  this.target.__render(this.canvas, options)
150
- if (Debug.showHitView) renderHitView(this.target, this.canvas, options)
182
+
183
+ this.renderBounds = realBounds || bounds
184
+ this.renderOptions = options
185
+ this.totalBounds.isEmpty() ? this.totalBounds = this.renderBounds : this.totalBounds.add(this.renderBounds)
186
+
187
+ if (Debug.showHitView) this.renderHitView(options)
188
+ if (Debug.showBoundsView) this.renderBoundsView(options)
151
189
  }
152
190
 
191
+ public renderHitView(_options: IRenderOptions): void { }
192
+
193
+ public renderBoundsView(_options: IRenderOptions): void { }
194
+
153
195
  public addBlock(block: IBounds): void {
154
196
  if (!this.updateBlocks) this.updateBlocks = []
155
197
  this.updateBlocks.push(block)
@@ -165,10 +207,6 @@ export class Renderer implements IRenderer {
165
207
  }
166
208
  }
167
209
 
168
- protected __checkAgain(): void {
169
- //if (this.changed && this.times < 3) this.target.emit(RenderEvent.AGAIN)
170
- }
171
-
172
210
  protected __requestRender(): void {
173
211
  const startTime = Date.now()
174
212
  Platform.requestRender(() => {
@@ -180,18 +218,34 @@ export class Renderer implements IRenderer {
180
218
  }
181
219
 
182
220
  protected __onResize(e: ResizeEvent): void {
221
+ if (this.canvas.unreal) return
183
222
  if (e.bigger || !e.samePixelRatio) {
184
223
  const { width, height } = e.old
185
224
  const bounds = new Bounds(0, 0, width, height)
186
- if (!bounds.includes(this.target.__world)) {
187
- this.target.__updateAttr('fill')
188
- this.update()
225
+ if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
226
+ this.addBlock(this.canvas.bounds)
227
+ this.target.forceUpdate('blendMode')
189
228
  }
190
229
  }
191
230
  }
192
231
 
193
232
  protected __onLayoutEnd(event: LayoutEvent): void {
194
- event.data?.map(item => this.addBlock(item.updatedBounds))
233
+ if (event.data) event.data.map(item => {
234
+ let empty: boolean
235
+ if (item.updatedList) item.updatedList.list.some(leaf => {
236
+ empty = (!leaf.__world.width || !leaf.__world.height)
237
+ if (empty) {
238
+ debug.warn(leaf.innerName, ': none bounds')
239
+ empty = (!leaf.isBranch || leaf.isBranchLeaf) // render object
240
+ }
241
+ return empty
242
+ })
243
+ this.addBlock(empty ? this.canvas.bounds : item.updatedBounds)
244
+ })
245
+ }
246
+
247
+ protected emitRender(type: string, bounds?: IBounds, options?: IRenderOptions): void {
248
+ this.target.emitEvent(new RenderEvent(type, this.times, bounds, options))
195
249
  }
196
250
 
197
251
  protected __listenEvents(): void {
@@ -199,7 +253,7 @@ export class Renderer implements IRenderer {
199
253
  this.__eventIds = [
200
254
  target.on__(RenderEvent.REQUEST, this.update, this),
201
255
  target.on__(LayoutEvent.END, this.__onLayoutEnd, this),
202
- target.on__(RenderEvent.AGAIN, this.renderOnce, this),
256
+ target.on__(RenderEvent.AGAIN, this.renderAgain, this),
203
257
  target.on__(ResizeEvent.RESIZE, this.__onResize, this)
204
258
  ]
205
259
  }
@@ -8,7 +8,7 @@ for (let i = 0; i < 360; i++) {
8
8
 
9
9
  export function renderHitView(target: ILeaf, canvas: ILeaferCanvas, options: IRenderOptions, hasMask?: boolean): void {
10
10
  if (target.hittable) {
11
- if (target.__isBranch) {
11
+ if (target.isBranch) {
12
12
  renderBranchHitView(target, canvas, options)
13
13
  } else {
14
14
  renderLeafHitView(target, canvas, options, hasMask)
@@ -22,7 +22,7 @@ export function renderBranchHitView(branch: ILeaf, canvas: ILeaferCanvas, option
22
22
  for (let i = 0, len = children.length; i < len; i++) {
23
23
  target = children[i]
24
24
  if (target.hittable) {
25
- if (target.__isBranch) {
25
+ if (target.isBranch) {
26
26
  renderBranchHitView(target, canvas, options)
27
27
  } else {
28
28
  renderLeafHitView(target, canvas, options, target.__hasMask)
@@ -33,7 +33,8 @@ export function renderBranchHitView(branch: ILeaf, canvas: ILeaferCanvas, option
33
33
 
34
34
  function renderLeafHitView(leaf: ILeaf, canvas: ILeaferCanvas, options: IRenderOptions, hasMask: boolean): void {
35
35
  if (leaf.__worldOpacity) {
36
- const { isMask, __strokeOuterWidth: strokeWidth } = leaf.__
36
+ const { isMask } = leaf.__
37
+ const { shapeStrokeSpreadWidth: strokeWidth } = leaf.__layout
37
38
  if (hasMask && !isMask) return
38
39
 
39
40
  canvas.setWorld(leaf.__world, options.matrix)