Skip to content

Commit

Permalink
Introduce a strictBounds flag (#404)
Browse files Browse the repository at this point in the history
Enabling strictBounds will not render / process nodes that are outside
of the visible area, otherwise the default behavior will render all
nodes regardless of their boundary status.
  • Loading branch information
erikhaandrikman authored Oct 1, 2024
2 parents 9957904 + 3f04e99 commit 9c01b8b
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 3 deletions.
92 changes: 92 additions & 0 deletions examples/tests/viewport-strictbounds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import type { ExampleSettings } from '../common/ExampleSettings.js';

export async function automation(settings: ExampleSettings) {
const page = await test(settings);
page(1);
await settings.snapshot();

page(2);
await settings.snapshot();

page(3);
await settings.snapshot();
}

export default async function test({ renderer, testRoot }: ExampleSettings) {
// Create a container node
const containerNode = renderer.createNode({
x: 10,
y: 100,
width: 1000,
height: 600,
color: 0xff0000ff, // Red
parent: testRoot,
});

const status = renderer.createTextNode({
text: 'Strict Bound: ',
fontSize: 30,
x: 10,
y: 50,
parent: testRoot,
});

const amountOfNodes = 11;
const childNodeWidth = 1700 / amountOfNodes;

// Create 11 child nodes
for (let i = 0; i < amountOfNodes; i++) {
const childNode = renderer.createNode({
x: i * childNodeWidth + i * 100,
y: 100,
width: childNodeWidth,
height: 300,
color: 0x00ff00ff, // Green
parent: containerNode,
});

const nodeTest = renderer.createTextNode({
x: 10,
y: 130,
text: `Node ${i}`,
color: 0x000000ff,
parent: childNode,
});
}

renderer.on('idle', () => {
status.text = 'Strict Bound: ' + String(containerNode.strictBounds);
});

window.onkeydown = (e) => {
if (e.key === 'ArrowRight') {
containerNode.x -= 100;
}

if (e.key === 'ArrowLeft') {
containerNode.x += 100;
}

if (e.key === ' ') {
containerNode.strictBounds = !containerNode.strictBounds;
}
};

const page = (i = 0) => {
switch (i) {
case 1:
containerNode.x = -590;
break;

case 2:
containerNode.x = -1390;
break;

case 3:
containerNode.strictBounds = true;
break;
}
};

return page;
}
1 change: 1 addition & 0 deletions src/core/CoreNode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ describe('set color()', () => {
zIndex: 0,
zIndexLocked: 0,
preventCleanup: false,
strictBounds: false,
};

it('should set all color subcomponents.', () => {
Expand Down
34 changes: 33 additions & 1 deletion src/core/CoreNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,21 @@ export interface CoreNodeProps {
* are provided. Only works when createImageBitmap is supported on the browser.
*/
srcY?: number;
/**
* By enabling Strict bounds the renderer will not process & render child nodes of a node that is out of the visible area
*
* @remarks
* When enabled out of bound nodes, i.e. nodes that are out of the visible area, will
* **NOT** have their children processed and renderer anymore. This means the children of a out of bound
* node will not receive update processing such as positioning updates and will not be drawn on screen.
* As such the rest of the branch of the update tree that sits below this node will not be processed anymore
*
* This is a big performance gain but may be disabled in cases where the width of the parent node is
* unknown and the render must process the child nodes regardless of the viewport status of the parent node
*
* @default false
*/
strictBounds: boolean;
}

/**
Expand Down Expand Up @@ -1101,7 +1116,10 @@ export class CoreNode extends EventEmitter {
parent.setUpdateType(UpdateType.ZIndexSortedChildren);
}

if (this.renderState === CoreNodeRenderState.OutOfBounds) {
if (
this.props.strictBounds === true &&
this.renderState === CoreNodeRenderState.OutOfBounds
) {
return;
}

Expand Down Expand Up @@ -2134,6 +2152,20 @@ export class CoreNode extends EventEmitter {
return this.props.textureOptions;
}

get strictBounds(): boolean {
return this.props.strictBounds;
}

set strictBounds(v) {
if (v === this.props.strictBounds) {
return;
}

this.props.strictBounds = v;
this.setUpdateType(UpdateType.RenderBounds | UpdateType.Children);
this.childUpdateType |= UpdateType.RenderBounds | UpdateType.Children;
}

setRTTUpdates(type: number) {
this.hasRTTupdates = true;
this.parent?.setRTTUpdates(type);
Expand Down
14 changes: 12 additions & 2 deletions src/core/Stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
import { startLoop, getTimeStamp } from './platform.js';
import { assertTruthy, setPremultiplyMode } from '../utils.js';
import { AnimationManager } from './animations/AnimationManager.js';
import { CoreNode, type CoreNodeProps } from './CoreNode.js';
import {
CoreNode,
CoreNodeRenderState,
type CoreNodeProps,
} from './CoreNode.js';
import { CoreTextureManager } from './CoreTextureManager.js';
import { TrFontManager } from './text-rendering/TrFontManager.js';
import { CoreShaderManager, type ShaderMap } from './CoreShaderManager.js';
Expand Down Expand Up @@ -240,6 +244,7 @@ export class Stage {
src: null,
scale: 1,
preventCleanup: false,
strictBounds: false,
});

this.root = rootNode;
Expand Down Expand Up @@ -397,7 +402,11 @@ export class Stage {
continue;
}

if (child.worldAlpha === 0) {
if (
child.worldAlpha === 0 ||
(child.strictBounds === true &&
child.renderState === CoreNodeRenderState.OutOfBounds)
) {
continue;
}

Expand Down Expand Up @@ -617,6 +626,7 @@ export class Stage {
data: data,
preventCleanup: props.preventCleanup ?? false,
imageType: props.imageType,
strictBounds: props.strictBounds ?? false,
};
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9c01b8b

Please sign in to comment.