Skip to content

Commit

Permalink
Fix for maplibre#3935 - pan-jump when map is large
Browse files Browse the repository at this point in the history
When the map canvas is large - >2048px, probably - the coords canvas
stops growing with the map due to web GL limitations.
This means that a screen-pixel is no longer 1:1 with a coords-canvas
pixel. It needs to be scaled using the ratio of devicePixelRatio and
painter.pixelRatio, which are no longer equal when the map is large.
  • Loading branch information
olsen232 committed Apr 3, 2024
1 parent f4d9a67 commit 0289a41
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/render/terrain.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('Terrain', () => {
context: new Context(gl),
width: 1,
height: 1,
pixelRatio: 1,
transform: {center: {lng: 0}},
maybeDrawDepthAndCoords: jest.fn(),
} as any as Painter;
Expand Down Expand Up @@ -70,6 +71,7 @@ describe('Terrain', () => {
context: new Context(gl),
width: WORLD_WIDTH,
height: 1,
pixelRatio: 1,
maybeDrawDepthAndCoords: jest.fn(),
} as any as Painter;
const sourceCache = {} as SourceCache;
Expand Down
5 changes: 4 additions & 1 deletion src/render/terrain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,12 @@ export class Terrain {

const rgba = new Uint8Array(4);
const context = this.painter.context, gl = context.gl;
const px = Math.round(p.x * this.painter.pixelRatio / devicePixelRatio);
const py = Math.round(p.y * this.painter.pixelRatio / devicePixelRatio);
const textureHeight = Math.round(this.painter.height / devicePixelRatio);
// grab coordinate pixel from coordinates framebuffer
context.bindFramebuffer.set(this.getFramebuffer('coords').framebuffer);
gl.readPixels(p.x, this.painter.height / devicePixelRatio - p.y - 1, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba);
gl.readPixels(px, textureHeight - py - 1, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, rgba);
context.bindFramebuffer.set(null);
// decode coordinates (encoding see getCoordsTexture)
const x = rgba[0] + ((rgba[2] >> 4) << 8);
Expand Down

0 comments on commit 0289a41

Please sign in to comment.