@leafer/renderer
Advanced tools
+7
-7
| { | ||
| "name": "@leafer/renderer", | ||
| "version": "1.0.0-alpha.9", | ||
| "version": "1.0.0-alpha.10", | ||
| "description": "@leafer/renderer", | ||
@@ -22,11 +22,11 @@ "author": "Chao (Leafer) Wan", | ||
| "dependencies": { | ||
| "@leafer/event": "1.0.0-alpha.9", | ||
| "@leafer/math": "1.0.0-alpha.9", | ||
| "@leafer/data": "1.0.0-alpha.9", | ||
| "@leafer/platform": "1.0.0-alpha.9", | ||
| "@leafer/debug": "1.0.0-alpha.9" | ||
| "@leafer/event": "1.0.0-alpha.10", | ||
| "@leafer/math": "1.0.0-alpha.10", | ||
| "@leafer/data": "1.0.0-alpha.10", | ||
| "@leafer/platform": "1.0.0-alpha.10", | ||
| "@leafer/debug": "1.0.0-alpha.10" | ||
| }, | ||
| "devDependencies": { | ||
| "@leafer/interface": "1.0.0-alpha.9" | ||
| "@leafer/interface": "1.0.0-alpha.10" | ||
| } | ||
| } |
+95
-88
@@ -1,2 +0,2 @@ | ||
| import { ILeaf, ILeaferCanvas, IRenderer, IRendererConfig, IEventListenerId, IBounds, IFunction, ILayoutBlockData } from '@leafer/interface' | ||
| import { ILeaf, ILeaferCanvas, IRenderer, IRendererConfig, IEventListenerId, IBounds, IFunction } from '@leafer/interface' | ||
| import { LayoutEvent, RenderEvent, ResizeEvent } from '@leafer/event' | ||
@@ -9,2 +9,4 @@ import { Bounds } from '@leafer/math' | ||
| const debug = Debug.get('Renderer') | ||
| export class Renderer implements IRenderer { | ||
@@ -14,30 +16,18 @@ | ||
| public canvas: ILeaferCanvas | ||
| public layoutedBlocks: ILayoutBlockData[] | ||
| public updateBlocks: IBounds[] | ||
| public FPS = 60 | ||
| public totalTimes = 0 | ||
| public times: number = 0 | ||
| public FPS = 60 | ||
| public running: boolean | ||
| public changed: boolean | ||
| public config: IRendererConfig = { | ||
| usePartRender: true, | ||
| maxFPS: 60 | ||
| } | ||
| public running: boolean | ||
| protected __eventIds: IEventListenerId[] | ||
| private _changed = false | ||
| set changed(value: boolean) { | ||
| if (value) { | ||
| if (!this._changed) { | ||
| this._changed = true | ||
| this.requestRender() | ||
| } | ||
| } else { | ||
| this._changed = false | ||
| } | ||
| } | ||
| get changed(): boolean { return this._changed } | ||
| protected eventIds: IEventListenerId[] | ||
| constructor(target: ILeaf, canvas: ILeaferCanvas, userConfig: IRendererConfig) { | ||
@@ -47,3 +37,3 @@ this.target = target | ||
| if (userConfig) this.config = DataHelper.default(userConfig, this.config) | ||
| this.listenEvents() | ||
| this.__listenEvents() | ||
| } | ||
@@ -53,3 +43,2 @@ | ||
| this.running = true | ||
| this.changed = true | ||
| } | ||
@@ -61,28 +50,4 @@ | ||
| private listenEvents(): void { | ||
| const { target } = this | ||
| this.eventIds = [ | ||
| target.on__(RenderEvent.REQUEST, this.onRequest, this), | ||
| target.on__(LayoutEvent.END, this.onLayoutEnd, this), | ||
| target.on__(RenderEvent.AGAIN, this.renderOnce, this), | ||
| target.on__(ResizeEvent.RESIZE, this.onResize, this) | ||
| ] | ||
| } | ||
| private removeListenEvents(): void { | ||
| this.target.off__(this.eventIds) | ||
| } | ||
| protected onResize(e: ResizeEvent): void { | ||
| if (e.bigger || !e.samePixelRatio) { | ||
| const { width, height } = e.old | ||
| const bounds = new Bounds(0, 0, width, height) | ||
| if (!bounds.includes(this.target.__world)) { | ||
| this.target.__updateAttr('fill') | ||
| this.changed = true | ||
| } | ||
| } | ||
| } | ||
| protected onRequest(): void { | ||
| public update(): void { | ||
| if (!this.changed) this.__requestRender() | ||
| this.changed = true | ||
@@ -95,14 +60,14 @@ } | ||
| public onLayoutEnd(event: LayoutEvent): void { | ||
| this.layoutedBlocks = event.data | ||
| } | ||
| public render(callback?: IFunction): void { | ||
| const { target } = this | ||
| const { START, RENDER, END } = RenderEvent | ||
| this.times = 0 | ||
| target.emit(START) | ||
| debug.log(target.innerId, '--->') | ||
| target.emit(RenderEvent.START) | ||
| this.renderOnce(callback) | ||
| target.emit(RENDER) | ||
| target.emit(END) | ||
| target.emit(RenderEvent.RENDER) | ||
| target.emit(RenderEvent.END) | ||
| debug.log(target.innerId, '---|') | ||
| } | ||
@@ -112,3 +77,2 @@ | ||
| const { target } = this | ||
| const { BEFORE_ONCE, ONCE, AFTER_ONCE } = RenderEvent | ||
@@ -121,3 +85,3 @@ this.times++ | ||
| target.emit(BEFORE_ONCE) | ||
| target.emit(RenderEvent.BEFORE_ONCE) | ||
@@ -130,6 +94,6 @@ callback() | ||
| target.emit(BEFORE_ONCE) | ||
| target.emit(RenderEvent.BEFORE_ONCE) | ||
| if (this.totalTimes > 1) { | ||
| if (this.layoutedBlocks) this.partRender() | ||
| if (this.config.usePartRender && this.totalTimes > 1) { | ||
| this.partRender() | ||
| } else { | ||
@@ -141,10 +105,7 @@ this.fullRender() | ||
| target.emit(ONCE) | ||
| target.emit(AFTER_ONCE) | ||
| target.emit(RenderEvent.ONCE) | ||
| target.emit(RenderEvent.AFTER_ONCE) | ||
| if (this.layoutedBlocks) { | ||
| this.layoutedBlocks.forEach(item => { item.destroy() }) | ||
| this.layoutedBlocks = undefined | ||
| } | ||
| this.updateBlocks = null | ||
@@ -154,17 +115,17 @@ this.__checkAgain() | ||
| protected __checkAgain(): void { | ||
| if (this.changed && this.times < 3) this.target.emit(RenderEvent.AGAIN) | ||
| } | ||
| public partRender(): void { | ||
| const { canvas, updateBlocks: list } = this | ||
| if (!list) { | ||
| debug.warn('PartRender: layoutedBlocks is empty') | ||
| this.fullRender(canvas.bounds) | ||
| return | ||
| } | ||
| protected partRender(): void { | ||
| const { canvas, layoutedBlocks } = this | ||
| if (layoutedBlocks.some(block => block.updatedBounds.includes(this.target.__world))) { | ||
| this.fullRender(canvas.bounds) | ||
| if (list.some(block => block.includes(this.target.__world))) { | ||
| this.mergeBlocks() | ||
| this.clipRender(this.updateBlocks[0], true) | ||
| } else { | ||
| let bounds: IBounds | ||
| layoutedBlocks.forEach(block => { | ||
| bounds = block.updatedBounds | ||
| if (canvas.bounds.hit(bounds) && !bounds.isEmpty()) this.clipRender(bounds.getIntersect(canvas.bounds)) | ||
| list.forEach(block => { | ||
| if (canvas.bounds.hit(block) && !block.isEmpty()) this.clipRender(block.getIntersect(canvas.bounds)) | ||
| }) | ||
@@ -174,4 +135,4 @@ } | ||
| public clipRender(bounds: IBounds): void { | ||
| const t = Run.start('part render') | ||
| public clipRender(bounds: IBounds, fullMode?: boolean): void { | ||
| const t = Run.start('PartRender') | ||
| const { canvas, target } = this | ||
@@ -183,3 +144,3 @@ | ||
| canvas.clipBounds(bounds) | ||
| target.__render(canvas, { bounds }) | ||
| target.__render(canvas, fullMode ? {} : { bounds }) | ||
| canvas.restore() | ||
@@ -193,7 +154,6 @@ | ||
| Renderer.fullRender(target, canvas, bounds) | ||
| if (Debug.showRepaint) canvas.strokeBounds(bounds || canvas.bounds, 'red') | ||
| } | ||
| static fullRender(target: ILeaf, canvas: ILeaferCanvas, bounds?: IBounds): void { | ||
| const t = Run.start('full render') | ||
| const t = Run.start('FullRender') | ||
| if (!bounds) bounds = canvas.bounds | ||
@@ -209,3 +169,21 @@ | ||
| private requestRender(): void { | ||
| public addBlock(block: IBounds): void { | ||
| if (!this.updateBlocks) this.updateBlocks = [] | ||
| this.updateBlocks.push(block) | ||
| } | ||
| public mergeBlocks(): void { | ||
| const { updateBlocks } = this | ||
| if (updateBlocks) { | ||
| const bounds = new Bounds() | ||
| bounds.setByList(updateBlocks) | ||
| this.updateBlocks = [bounds] | ||
| } | ||
| } | ||
| protected __checkAgain(): void { | ||
| if (this.changed && this.times < 3) this.target.emit(RenderEvent.AGAIN) | ||
| } | ||
| protected __requestRender(): void { | ||
| const startTime = Date.now() | ||
@@ -220,10 +198,39 @@ Platform.requestRender(() => { | ||
| protected __onResize(e: ResizeEvent): void { | ||
| if (e.bigger || !e.samePixelRatio) { | ||
| const { width, height } = e.old | ||
| const bounds = new Bounds(0, 0, width, height) | ||
| if (!bounds.includes(this.target.__world)) { | ||
| this.target.__updateAttr('fill') | ||
| this.update() | ||
| } | ||
| } | ||
| } | ||
| protected __onLayoutEnd(event: LayoutEvent): void { | ||
| event.data.map(item => this.addBlock(item.updatedBounds)) | ||
| } | ||
| protected __listenEvents(): void { | ||
| const { target } = this | ||
| this.__eventIds = [ | ||
| target.on__(RenderEvent.REQUEST, this.update, this), | ||
| target.on__(LayoutEvent.END, this.__onLayoutEnd, this), | ||
| target.on__(RenderEvent.AGAIN, this.renderOnce, this), | ||
| target.on__(ResizeEvent.RESIZE, this.__onResize, this) | ||
| ] | ||
| } | ||
| protected __removeListenEvents(): void { | ||
| this.target.off__(this.__eventIds) | ||
| } | ||
| public destroy(): void { | ||
| if (this.target) { | ||
| this.removeListenEvents() | ||
| this.target = undefined | ||
| this.canvas = undefined | ||
| this.config = undefined | ||
| this.__removeListenEvents() | ||
| this.target = null | ||
| this.canvas = null | ||
| this.config = null | ||
| } | ||
| } | ||
| } |
7895
1.99%170
1.8%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated