diff --git a/src/core/render/container.ts b/src/core/render/container.ts index 6ba73da..5a68866 100644 --- a/src/core/render/container.ts +++ b/src/core/render/container.ts @@ -46,7 +46,7 @@ export class Container }); } - private requestSort() { + requestSort() { if (!this.needSort) { this.needSort = true; this.requestBeforeFrame(() => { @@ -62,11 +62,8 @@ export class Container */ appendChild(...children: RenderItem[]) { children.forEach(v => { - v.remove(); - this.children.add(v); - v.parent = this; + v.append(this); }); - children.forEach(v => (v.parent = this)); this.requestSort(); this.update(this); } @@ -74,15 +71,16 @@ export class Container removeChild(...child: RenderItem[]): void { let changed = false; child.forEach(v => { - const success = this.children.delete(v); - if (success) changed = true; - v.parent = void 0; + const success = v.remove(); + if (success) { + changed = true; + } }); if (changed) this.requestSort(); this.update(this); } - sortChildren() { + private sortChildren() { this.sortedChildren = [...this.children].sort( (a, b) => a.zIndex - b.zIndex ); diff --git a/src/core/render/gl.ts b/src/core/render/gl.ts deleted file mode 100644 index 15a2bf5..0000000 --- a/src/core/render/gl.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { MotaOffscreenCanvas2D, MotaOffscreenCanvasGL2 } from '../fx/canvas2d'; -import { RenderItem } from './item'; -import { Transform } from './transform'; - -type GL2RenderFunc = ( - canvas: MotaOffscreenCanvasGL2, - transform: Transform -) => void; - -export class GL2 extends RenderItem { - canvas: MotaOffscreenCanvasGL2 = new MotaOffscreenCanvasGL2(); - - /** 渲染函数 */ - private renderFn: GL2RenderFunc = () => {}; - - protected render( - canvas: MotaOffscreenCanvas2D, - transform: Transform - ): void { - const gl = this.canvas.gl; - gl.viewport(0, 0, this.canvas.width, this.canvas.height); - - gl.clearColor(0, 0, 0, 0); - gl.clearDepth(1); - gl.enable(gl.DEPTH_TEST); - gl.depthFunc(gl.LEQUAL); - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - - this.renderFn(this.canvas, transform); - canvas.ctx.drawImage(this.canvas.canvas, 0, 0, this.width, this.height); - } - - /** - * 设置这个gl2元素的渲染函数 - * @param fn 渲染函数 - */ - setRenderFn(fn: GL2RenderFunc) { - this.renderFn = fn; - } -} diff --git a/src/core/render/item.ts b/src/core/render/item.ts index a1b8239..52cbf1a 100644 --- a/src/core/render/item.ts +++ b/src/core/render/item.ts @@ -67,9 +67,9 @@ export interface IRenderChildable { removeChild(...child: RenderItem[]): void; /** - * 对子元素进行排序 + * 在下一个tick的渲染前对子元素进行排序 */ - sortChildren(): void; + requestSort(): void; } interface IRenderFrame { @@ -162,11 +162,13 @@ export abstract class RenderItem return this._id; } set id(v: string) { - if (RenderItem.itemMap.has(this._id)) { - logger.warn(23); - RenderItem.itemMap.delete(this._id); + if (this.isRoot || this.findRoot()) { + if (RenderItem.itemMap.has(this._id)) { + logger.warn(23); + RenderItem.itemMap.delete(this._id); + } + RenderItem.itemMap.set(v, this); } - RenderItem.itemMap.set(v, this); this._id = v; } @@ -193,6 +195,8 @@ export abstract class RenderItem /** 当前元素的父元素 */ parent?: RenderItem & IRenderChildable; + /** 当前元素是否为根元素 */ + readonly isRoot: boolean = false; protected needUpdate: boolean = false; @@ -222,6 +226,18 @@ export abstract class RenderItem this.cache.withGameScale(true); } + private findRoot() { + let ele: RenderItem = this; + while (!ele.isRoot) { + if (!ele.parent) { + return null; + } else { + ele = ele.parent; + } + } + return ele; + } + /** * 渲染函数 * @param canvas 渲染至的画布 @@ -338,7 +354,7 @@ export abstract class RenderItem setZIndex(zIndex: number) { this.zIndex = zIndex; - this.parent?.sortChildren?.(); + this.parent?.requestSort(); } requestBeforeFrame(fn: () => void): void { @@ -407,15 +423,27 @@ export abstract class RenderItem * 将这个渲染元素添加到其他父元素上 * @param parent 父元素 */ - append(parent: IRenderChildable) { - parent.appendChild(this); + append(parent: IRenderChildable & RenderItem) { + this.remove(); + parent.children.add(this); + this.parent = parent; + if (this._id !== '') { + const root = this.findRoot(); + if (!root) return; + RenderItem.itemMap.set(this._id, this); + } } /** * 从渲染树中移除这个节点 */ - remove() { - this.parent?.removeChild(this); + remove(): boolean { + if (!this.parent) return false; + const success = this.parent.children.delete(this); + this.parent = void 0; + if (!success) return false; + RenderItem.itemMap.delete(this._id); + return true; } /** @@ -431,19 +459,16 @@ export abstract class RenderItem RenderItem.ticker.add(() => { if (beforeFrame.length > 0) { - const toEmit = beforeFrame.slice(); + beforeFrame.forEach(v => v()); beforeFrame.splice(0); - toEmit.forEach(v => v()); } if (renderFrame.length > 0) { - const toEmit = renderFrame.slice(); + renderFrame.forEach(v => v()); renderFrame.splice(0); - toEmit.forEach(v => v()); } if (afterFrame.length > 0) { - const toEmit = afterFrame.slice(); + afterFrame.forEach(v => v()); afterFrame.splice(0); - toEmit.forEach(v => v()); } }); diff --git a/src/core/render/render.ts b/src/core/render/render.ts index b6afca2..2fa059d 100644 --- a/src/core/render/render.ts +++ b/src/core/render/render.ts @@ -9,6 +9,7 @@ export class MotaRenderer extends Container { target: MotaCanvas2D; protected needUpdate: boolean = false; + readonly isRoot: boolean = true; constructor(id: string = 'render-main') { super('static', false); @@ -37,10 +38,8 @@ export class MotaRenderer extends Container { protected refresh(item?: RenderItem): void { this.emit('beforeUpdate', item); - // console.time(); this.target.clear(); this.renderContent(this.target, Transform.identity); - // console.timeEnd(); this.emit('afterUpdate', item); }