Skip to content

Commit

Permalink
Unload textures if Canvas text is out of bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
wouterlucas committed May 21, 2024
1 parent de7ab29 commit 66a5056
Show file tree
Hide file tree
Showing 2 changed files with 203 additions and 8 deletions.
192 changes: 192 additions & 0 deletions examples/tests/viewport-events-canvas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import type { IAnimationController } from '../../dist/exports/main-api.js';
import type { ExampleSettings } from '../common/ExampleSettings.js';
import test from './alpha-blending.js';

export default async function ({ renderer, testRoot }: ExampleSettings) {
const instructionText = renderer.createTextNode({
text: 'Press space to start animation, arrow keys to move, enter to reset',
fontSize: 30,
x: 10,
y: 960,
fontFamily: 'Ubuntu-ssdf',
parent: testRoot,
});

const redStatus = renderer.createTextNode({
text: 'Red Status: ',
fontSize: 30,
x: 10,
y: 50,
fontFamily: 'Ubuntu-ssdf',
parent: testRoot,
});

const blueStatus = renderer.createTextNode({
text: 'Blue Status: ',
fontSize: 30,
x: 10,
y: 10,
fontFamily: 'Ubuntu-ssdf',
parent: testRoot,
});

const boundaryRect = renderer.createNode({
x: 1920 / 2 - (1920 * 0.75) / 2,
y: 1080 / 2 - (1080 * 0.75) / 2,
width: 1440,
height: 810,
color: 0x000000ff,
clipping: true,
parent: testRoot,
});

const redText = renderer.createTextNode({
x: -300,
y: 305,
alpha: 1,
width: 200,
height: 200,
color: 0xff0000ff,
pivot: 0,
text: 'red',
fontSize: 80,
fontFamily: 'sans-serif',
parent: boundaryRect,
});

redText.on('outOfBounds', () => {
console.log('red text out of bounds');
redStatus.text = 'Red Status: text out of bounds';
redStatus.color = 0xff0000ff;
});

redText.on('inViewport', () => {
console.log('red text in view port');
redStatus.text = 'Red Status: text in view port';
redStatus.color = 0x00ff00ff;
});

redText.on('inBounds', () => {
console.log('red text inside render bounds');
redStatus.text = 'Red Status: text in bounds';
redStatus.color = 0xffff00ff;
});

const blueText = renderer.createTextNode({
// x: 1920 / 2 - 200,
x: 0,
y: 100,
alpha: 1,
width: 200,
height: 200,
color: 0x0000ffff,
pivot: 0,
text: 'blue',
fontSize: 80,
fontFamily: 'sans-serif',
parent: testRoot,
});

blueText.on('outOfBounds', () => {
console.log('blue text ouf ot bounds');
blueStatus.text = 'Blue Status: blue text out of bounds';
blueStatus.color = 0xff0000ff;
});

blueText.on('inViewport', () => {
console.log('blue text in view port');
blueStatus.text = 'Blue Status: blue text in view port';
blueStatus.color = 0x00ff00ff;
});

blueText.on('inBounds', () => {
console.log('blue text inside render bounds');
blueStatus.text = 'Blue Status: blue text in bounds';
blueStatus.color = 0xffff00ff;
});

let runAnimation = false;
const animate = async () => {
redText
.animate(
{
x: -500,
},
{
duration: 4000,
},
)
.start();

await blueText
.animate(
{
x: -1200,
},
{
duration: 4000,
},
)
.start()
.waitUntilStopped();

redText.x = 1920 + 400;
blueText.x = 1920 + 400;

redText
.animate(
{
x: 520,
},
{
duration: 4000,
},
)
.start();

await blueText
.animate(
{
x: 1920 / 2 - 200,
},
{
duration: 4000,
},
)
.start()
.waitUntilStopped();

if (runAnimation) {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
setTimeout(animate, 2000);
}
};

const moveModifier = 10;
window.onkeydown = (e) => {
if (e.key === ' ') {
runAnimation = !runAnimation;

if (runAnimation) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
animate();
}
}

if (e.key === 'ArrowRight') {
redText.x += moveModifier;
blueText.x += moveModifier;
}

if (e.key === 'ArrowLeft') {
redText.x -= moveModifier;
blueText.x -= moveModifier;
}

if (e.key === 'Enter') {
runAnimation = false;
redText.x = 520;
blueText.x = 1920 / 2 - 200;
}
};
}
19 changes: 11 additions & 8 deletions src/core/text-rendering/renderers/CanvasTextRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,11 @@ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
return;
}

// if it's not renderable, don't render anything
if (state.isRenderable === false) {
return;
}

if (!state.renderInfo) {
state.renderInfo = this.calculateRenderInfo(state);
}
Expand Down Expand Up @@ -681,9 +686,7 @@ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {

// Invalidate renderWindow because the renderInfo changed
state.renderWindow = undefined;

const renderInfo = state.lightning2TextRenderer.calculateRenderInfo();
return renderInfo;
return state.renderInfo;
}

getAndCalculateVisibleWindow(state: CanvasTextRendererState): BoundWithValid {
Expand Down Expand Up @@ -761,11 +764,9 @@ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
const { stage } = this;

const { canvasPages, textW = 0, textH = 0, renderWindow } = state;

if (!canvasPages || !renderWindow) return;

const { x, y, scrollY, contain, width, height /*, debug*/ } = state.props;

const elementRect = {
x: x,
y: y,
Expand Down Expand Up @@ -913,13 +914,15 @@ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
): void {
super.setIsRenderable(state, renderable);
// Set state object owner from any canvas page textures
state.canvasPages?.forEach((pageInfo) => {
pageInfo.texture?.setRenderableOwner(state, renderable);
});
// If the state is not renderable, we don't want to keep the texture
if (renderable === false) {
this.destroyState(state);
}
}

override destroyState(state: CanvasTextRendererState): void {
super.destroyState(state);

// Remove state object owner from any canvas page textures
state.canvasPages?.forEach((pageInfo) => {
const { texture } = pageInfo;
Expand Down

0 comments on commit 66a5056

Please sign in to comment.