diff --git a/src/core/CoreNode.ts b/src/core/CoreNode.ts index 1cff038b..f20f10f6 100644 --- a/src/core/CoreNode.ts +++ b/src/core/CoreNode.ts @@ -155,6 +155,7 @@ export class CoreNode extends EventEmitter implements ICoreNode { public scaleRotateTransform?: Matrix3d; public localTransform?: Matrix3d; public clippingRect: Rect | null = null; + public isRenderable = false; private parentClippingRect: Rect | null = null; public worldAlpha = 1; public premultipliedColorTl = 0; @@ -214,11 +215,13 @@ export class CoreNode extends EventEmitter implements ICoreNode { } this.props.texture = null; this.props.textureOptions = null; + this.checkIsRenderable(); } private onTextureLoaded: TextureLoadedEventHandler = (target, dimensions) => { // Texture was loaded. In case the RAF loop has already stopped, we request // a render to ensure the texture is rendered. + this.checkIsRenderable(); this.stage.requestRender(); this.emit('loaded', { type: 'texture', @@ -243,6 +246,7 @@ export class CoreNode extends EventEmitter implements ICoreNode { const { shader, props: p } = shManager.loadShader(shaderType, props); this.props.shader = shader; this.props.shaderProps = p; + this.checkIsRenderable(); } /** @@ -310,27 +314,23 @@ export class CoreNode extends EventEmitter implements ICoreNode { const parent = this.props.parent; let childUpdateType = UpdateType.None; if (this.updateType & UpdateType.Global) { + assertTruthy(this.localTransform); + this.globalTransform = Matrix3d.copy( + parent?.globalTransform || this.localTransform, + this.globalTransform, + ); + if (parent) { - assertTruthy(this.localTransform && parent.globalTransform); - this.globalTransform = Matrix3d.copy( - parent.globalTransform, - this.globalTransform, - ).multiply(this.localTransform); - this.setUpdateType(UpdateType.Clipping | UpdateType.Children); - childUpdateType |= UpdateType.Global; - } else { - assertTruthy(this.localTransform); - this.globalTransform = Matrix3d.copy( - this.localTransform, - this.globalTransform, - ); - this.setUpdateType(UpdateType.Clipping | UpdateType.Children); - childUpdateType |= UpdateType.Global; + this.globalTransform.multiply(this.localTransform); } + + this.setUpdateType(UpdateType.Clipping | UpdateType.Children); + childUpdateType |= UpdateType.Global; } if (this.updateType & UpdateType.Clipping) { this.calculateClippingRect(parentClippingRect); + this.checkIsRenderable(); this.setUpdateType(UpdateType.Children); childUpdateType |= UpdateType.Clipping; } @@ -346,49 +346,28 @@ export class CoreNode extends EventEmitter implements ICoreNode { } if (this.updateType & UpdateType.PremultipliedColors) { - if (parent) { - this.premultipliedColorTl = mergeColorAlphaPremultiplied( - this.props.colorTl, - this.worldAlpha, - true, - ); - this.premultipliedColorTr = mergeColorAlphaPremultiplied( - this.props.colorTr, - this.worldAlpha, - true, - ); - this.premultipliedColorBl = mergeColorAlphaPremultiplied( - this.props.colorBl, - this.worldAlpha, - true, - ); - this.premultipliedColorBr = mergeColorAlphaPremultiplied( - this.props.colorBr, - this.worldAlpha, - true, - ); - } else { - this.premultipliedColorTl = mergeColorAlphaPremultiplied( - this.props.colorTl, - this.worldAlpha, - true, - ); - this.premultipliedColorTr = mergeColorAlphaPremultiplied( - this.props.colorTr, - this.worldAlpha, - true, - ); - this.premultipliedColorBl = mergeColorAlphaPremultiplied( - this.props.colorBl, - this.worldAlpha, - true, - ); - this.premultipliedColorBr = mergeColorAlphaPremultiplied( - this.props.colorBr, - this.worldAlpha, - true, - ); - } + this.premultipliedColorTl = mergeColorAlphaPremultiplied( + this.props.colorTl, + this.worldAlpha, + true, + ); + this.premultipliedColorTr = mergeColorAlphaPremultiplied( + this.props.colorTr, + this.worldAlpha, + true, + ); + this.premultipliedColorBl = mergeColorAlphaPremultiplied( + this.props.colorBl, + this.worldAlpha, + true, + ); + this.premultipliedColorBr = mergeColorAlphaPremultiplied( + this.props.colorBr, + this.worldAlpha, + true, + ); + + this.checkIsRenderable(); this.setUpdateType(UpdateType.Children); childUpdateType |= UpdateType.PremultipliedColors; } @@ -423,6 +402,41 @@ export class CoreNode extends EventEmitter implements ICoreNode { this.updateType = 0; } + // This function checks if the current node is renderable based on certain properties. + // It returns true if any of the specified properties are truthy or if any color property is not 0, otherwise it returns false. + checkIsRenderable(): boolean { + if (this.props.texture) { + return (this.isRenderable = true); + } + + if (this.props.shader) { + return (this.isRenderable = true); + } + + if (this.props.clipping) { + return (this.isRenderable = true); + } + + const colors = [ + 'color', + 'colorTop', + 'colorBottom', + 'colorLeft', + 'colorRight', + 'colorTl', + 'colorTr', + 'colorBl', + 'colorBr', + ]; + if ( + colors.some((color) => this.props[color as keyof CoreNodeProps] !== 0) + ) { + return (this.isRenderable = true); + } + + return (this.isRenderable = false); + } + /** * This function calculates the clipping rectangle for a node. * diff --git a/src/core/CoreTextNode.ts b/src/core/CoreTextNode.ts index 519f5545..63780169 100644 --- a/src/core/CoreTextNode.ts +++ b/src/core/CoreTextNode.ts @@ -151,6 +151,7 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode { set text(value: string) { this.textRenderer.set.text(this.trState, value); + this.checkIsRenderable(); } get textRendererOverride(): CoreTextNodeProps['textRendererOverride'] { @@ -272,6 +273,18 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode { this.textRenderer.set.y(this.trState, this.globalTransform.ty); } + override checkIsRenderable(): boolean { + if (super.checkIsRenderable()) { + return true; + } + + if (this.trState.props.text !== '') { + return (this.isRenderable = true); + } + + return (this.isRenderable = false); + } + override renderQuads(renderer: CoreRenderer) { assertTruthy(this.globalTransform); this.textRenderer.renderQuads( diff --git a/src/core/Stage.ts b/src/core/Stage.ts index faabe89b..d01b9899 100644 --- a/src/core/Stage.ts +++ b/src/core/Stage.ts @@ -220,7 +220,10 @@ export class Stage extends EventEmitter { addQuads(node: CoreNode) { assertTruthy(this.renderer && node.globalTransform); - node.renderQuads(this.renderer); + if (node.isRenderable) { + node.renderQuads(this.renderer); + } + for (let i = 0; i < node.children.length; i++) { const child = node.children[i];