From 682d01456672383e83982ee64a9d9cef4a7e0877 Mon Sep 17 00:00:00 2001 From: Olivier Biot Date: Tue, 15 Sep 2026 07:23:38 +0800 Subject: [PATCH] deviceTest: the example rendered no text at all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nine calls used `font.draw(renderer, text, x, y)` — the old `Font` blitter signature. `Text#draw()` takes the renderer and nothing else, so the last three arguments were dropped on every call and the same label, constructed with no text, was drawn at (0, 0) each time. On screen: a red ball on black and nothing else. A `Text` is a renderable, so each readout is positioned and then drawn. `pos.x` / `pos.y` are assigned per component because `pos.set(x, y)` is the 2-argument form and zeroes z, which is `depth`. Two faults only became visible once text actually rendered: the default `textBaseline` put the first line at y = 0 mostly above the canvas, and the bottom message at `height - 30` was clipped. The baseline is now `top`, the lines start at 30, and the message sits at `height - 40`. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01NGvtaUNATVCVxD2qcbiY4t --- .../examples/deviceTest/ExampleDeviceTest.tsx | 48 ++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/packages/examples/src/examples/deviceTest/ExampleDeviceTest.tsx b/packages/examples/src/examples/deviceTest/ExampleDeviceTest.tsx index ad19c7c78..b9f14c88e 100644 --- a/packages/examples/src/examples/deviceTest/ExampleDeviceTest.tsx +++ b/packages/examples/src/examples/deviceTest/ExampleDeviceTest.tsx @@ -27,6 +27,9 @@ class DeviceInfo extends Renderable { font: "Arial", size: "24px", fillStyle: "#FFFFFF", + // so a line's `y` is the top of its box: without this the first + // readout at y = 0 sits mostly above the canvas and never shows + textBaseline: "top", }); this.anchorPoint.set(0, 0); } @@ -35,6 +38,29 @@ class DeviceInfo extends Renderable { return true; } + /** + * Draw one readout line. + * + * `Text` is a renderable, not the old `Font` blitter: `draw()` takes the + * renderer and nothing else, and the label goes where its `pos` says. The + * former `font.draw(renderer, text, x, y)` shape silently dropped the last + * three arguments, so every call here drew the same empty label at (0, 0) + * and the example rendered no text at all. + */ + private line( + renderer: WebGLRenderer | CanvasRenderer, + text: string, + x: number, + y: number, + ) { + // per component: `pos.set(x, y)` is the 2-argument form and zeroes z, + // which is `depth` + this.font.pos.x = x; + this.font.pos.y = y; + this.font.setText(text); + this.font.draw(renderer); + } + override draw(renderer: WebGLRenderer | CanvasRenderer) { // current device orientation ("portrait" or "landscape") const orientation = device.getScreenOrientation(); @@ -43,28 +69,28 @@ class DeviceInfo extends Renderable { renderer.setColor("#ffffff"); if (device.hasDeviceOrientation) { - this.font.draw( + this.line( renderer, "Touch to enable motion detection", 10, - game.viewport.height - 30, + game.viewport.height - 40, ); } else { - this.font.draw( + this.line( renderer, "Motion detection not supported", 10, - game.viewport.height - 30, + game.viewport.height - 40, ); } - this.font.draw(renderer, `Gamma: ${device.gamma}`, 10, 0); - this.font.draw(renderer, `Beta: ${device.beta}`, 10, 30); - this.font.draw(renderer, `Alpha: ${device.alpha}`, 10, 60); - this.font.draw(renderer, `X: ${device.accelerationX}`, 10, 90); - this.font.draw(renderer, `Y: ${device.accelerationY}`, 10, 120); - this.font.draw(renderer, `Z: ${device.accelerationZ}`, 10, 150); - this.font.draw(renderer, `orientation: ${orientation}`, 10, 180); + this.line(renderer, `Gamma: ${device.gamma}`, 10, 30); + this.line(renderer, `Beta: ${device.beta}`, 10, 60); + this.line(renderer, `Alpha: ${device.alpha}`, 10, 90); + this.line(renderer, `X: ${device.accelerationX}`, 10, 120); + this.line(renderer, `Y: ${device.accelerationY}`, 10, 150); + this.line(renderer, `Z: ${device.accelerationZ}`, 10, 180); + this.line(renderer, `orientation: ${orientation}`, 10, 210); // draw a red circle based on the device motion and orientation const deltaX =