Repository navigation
fix(rendering): map pointer coordinates over the unzoomed design space in screenToWorld - #862
Merged
Merged
Conversation
…e in screenToWorld
…zero-extent viewport
Exoridus
enabled auto-merge (squash)
October 22, 2026 10:30
Bundle ReportChanges will increase total bundle size by 963 bytes (0.0%) ⬆️. This is within the configured threshold ✅ Detailed changes
Affected Assets, Files, and Routes:view changes for bundle: exo-esm-esmAssets Changed:
Files in
view changes for bundle: site-server-esmAssets Changed:
view changes for bundle: exo-esm-modules-esmAssets Changed:
Files in
Files in
Files in
Files in
Files in
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
View.screenToWorld(x, y)mapped pointer coordinates wrongly whenever the zoom was not 1. The two-argument form used the visible size (view.width/view.height) as the span of the input coordinates, butsetZoom()shrinks or grows exactly that size while pointer coordinates stay in the unzoomed logical canvas space. Fornew View(400, 300, 800, 600)atsetZoom(2), the screen centre(400, 300)mapped to(600, 450)instead of(400, 300). The existing zoom round-trip test stayed green becauseworldToScreenmade the same assumption and cancelled the error.Contract
screenToWorld/worldToScreenmap over the view's design space: the unzoomed size given to the constructor,resize()orreset(). Zooming, or writingsizedirectly, changes how much world is visible, not which coordinates are accepted. A full-canvas view sized to the canvas therefore acceptspointer.x/pointer.yunchanged at every zoom level.app.width/app.heightfor pointer coordinates,app.canvas.width/app.canvas.heightfor backing-store pixels. A zero-extent viewport returns a finite point instead of NaN.app.screenToWorld(x, y)and pointer hit-testing now use the four-argument form over the logical canvas, so an active camera that covers only part of the canvas (split screen) or has a custom size maps correctly. This matches how both backends place a view: viewport fraction times the render surface.zoom(factor)no longer resets the design space (it used to go throughresize()and resetzoomLevelto 1); it now scales the current size and trackszoomLevel.RenderingContext.resize()keeps the active camera's zoom across canvas resizes, as its documentation already stated;View.resize()alone still resets zoom.Tests
Regression tests assert absolute world positions derived from the camera geometry, never round-trips: zoom 2 and 0.5, panned non-square camera, rotation, the backend projection (
getTransformonto the design surface),zoom(), direct size writes,View.from({ zoom }), zero-size construction, resize, the four-argument form for full and split viewports,Application.screenToWorldwith zoomed and split active cameras,InteractionSystemhits through a zoomed and a split-screen camera, and zoom preservation onRenderingContext.resize. Two existing tests (view-rotation-pivot,view-rotated-cull-bounds) had adapted their screen coordinates to the defect ("zoom shrinks the design space"); they now probe the design space and a unit surface respectively, with unchanged expectations about the rendered area.The coordinates guide's pointer snippet now converts over
app.width/app.height, which is correct for split views too; the pointer guide and API reference describe the contract above.This is a v0.20 correctness fix: code that compensated for the old mapping (for example by passing
view.widthas the input span) has to drop that compensation.