Scale tiles instead of canvas
This commit is contained in:
@@ -6,7 +6,7 @@ import TileRange from '../../TileRange.js';
|
|||||||
import TileState from '../../TileState.js';
|
import TileState from '../../TileState.js';
|
||||||
import {createEmpty, getIntersection, getTopLeft} from '../../extent.js';
|
import {createEmpty, getIntersection, getTopLeft} from '../../extent.js';
|
||||||
import CanvasLayerRenderer from './Layer.js';
|
import CanvasLayerRenderer from './Layer.js';
|
||||||
import {compose as composeTransform, makeInverse, toString as transformToString} from '../../transform.js';
|
import {apply as applyTransform, compose as composeTransform, makeInverse, toString as transformToString} from '../../transform.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @classdesc
|
* @classdesc
|
||||||
@@ -21,12 +21,6 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
|||||||
constructor(tileLayer) {
|
constructor(tileLayer) {
|
||||||
super(tileLayer);
|
super(tileLayer);
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.oversampling_;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {import("../../extent.js").Extent}
|
* @type {import("../../extent.js").Extent}
|
||||||
@@ -152,17 +146,6 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
|||||||
// desired dimensions of the canvas in pixels
|
// desired dimensions of the canvas in pixels
|
||||||
let width = Math.round(frameState.size[0] * tilePixelRatio);
|
let width = Math.round(frameState.size[0] * tilePixelRatio);
|
||||||
let height = Math.round(frameState.size[1] * tilePixelRatio);
|
let height = Math.round(frameState.size[1] * tilePixelRatio);
|
||||||
if (tileResolution < viewResolution) {
|
|
||||||
// scale canvas so it covers the viewport until new tiles come in
|
|
||||||
let scale;
|
|
||||||
if (z <= tileGrid.minZoom) {
|
|
||||||
scale = Math.round(viewResolution / tileResolution);
|
|
||||||
} else {
|
|
||||||
scale = 1.5; // rely on lower z tiles
|
|
||||||
}
|
|
||||||
width *= scale;
|
|
||||||
height *= scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rotation) {
|
if (rotation) {
|
||||||
const size = Math.round(Math.sqrt(width * width + height * height));
|
const size = Math.round(Math.sqrt(width * width + height * height));
|
||||||
@@ -178,7 +161,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
|||||||
viewCenter[1] + dy
|
viewCenter[1] + dy
|
||||||
];
|
];
|
||||||
|
|
||||||
const tileRange = tileGrid.getTileRangeForExtentAndZ(canvasExtent, z);
|
const tileRange = tileGrid.getTileRangeForExtentAndZ(frameState.extent, z);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Object<number, Object<string, import("../../Tile.js").default>>}
|
* @type {Object<number, Object<string, import("../../Tile.js").default>>}
|
||||||
@@ -224,17 +207,25 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
|||||||
|
|
||||||
|
|
||||||
const canvas = context.canvas;
|
const canvas = context.canvas;
|
||||||
const canvasScale = tileResolution / frameState.viewState.resolution / tilePixelRatio;
|
const canvasScale = tileResolution / viewResolution;
|
||||||
|
|
||||||
// set forward and inverse pixel transforms
|
// set forward and inverse pixel transforms
|
||||||
composeTransform(this.pixelTransform_,
|
composeTransform(this.pixelTransform_,
|
||||||
frameState.size[0] / 2, frameState.size[1] / 2,
|
frameState.size[0] / 2, frameState.size[1] / 2,
|
||||||
canvasScale, canvasScale,
|
1 / tilePixelRatio, 1 / tilePixelRatio,
|
||||||
rotation,
|
rotation,
|
||||||
-width / 2, -height / 2
|
-width / 2, -height / 2
|
||||||
);
|
);
|
||||||
makeInverse(this.inversePixelTransform_, this.pixelTransform_);
|
makeInverse(this.inversePixelTransform_, this.pixelTransform_);
|
||||||
|
|
||||||
|
// set scale transform for calculating tile positions on the canvas
|
||||||
|
composeTransform(this.tempTransform_,
|
||||||
|
width / 2, height / 2,
|
||||||
|
canvasScale, canvasScale,
|
||||||
|
0,
|
||||||
|
-width / 2, -height / 2
|
||||||
|
);
|
||||||
|
|
||||||
if (canvas.width != width || canvas.height != height) {
|
if (canvas.width != width || canvas.height != height) {
|
||||||
canvas.width = width;
|
canvas.width = width;
|
||||||
canvas.height = height;
|
canvas.height = height;
|
||||||
@@ -266,19 +257,30 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
|||||||
const currentTilePixelSize = tileSource.getTilePixelSize(currentZ, pixelRatio, projection);
|
const currentTilePixelSize = tileSource.getTilePixelSize(currentZ, pixelRatio, projection);
|
||||||
const currentResolution = tileGrid.getResolution(currentZ);
|
const currentResolution = tileGrid.getResolution(currentZ);
|
||||||
const currentScale = currentResolution / tileResolution;
|
const currentScale = currentResolution / tileResolution;
|
||||||
const w = currentTilePixelSize[0] * currentScale;
|
const dx = currentTilePixelSize[0] * currentScale * canvasScale;
|
||||||
const h = currentTilePixelSize[1] * currentScale;
|
const dy = currentTilePixelSize[1] * currentScale * canvasScale;
|
||||||
const originTileCoord = tileGrid.getTileCoordForCoordAndZ(getTopLeft(canvasExtent), currentZ);
|
const originTileCoord = tileGrid.getTileCoordForCoordAndZ(getTopLeft(canvasExtent), currentZ);
|
||||||
const originTileExtent = tileGrid.getTileCoordExtent(originTileCoord);
|
const originTileExtent = tileGrid.getTileCoordExtent(originTileCoord);
|
||||||
const originX = Math.round(tilePixelRatio * (originTileExtent[0] - canvasExtent[0]) / tileResolution);
|
const origin = applyTransform(this.tempTransform_, [
|
||||||
const originY = Math.round(tilePixelRatio * (canvasExtent[3] - originTileExtent[3]) / tileResolution);
|
Math.round(tilePixelRatio * (originTileExtent[0] - canvasExtent[0]) / tileResolution),
|
||||||
|
Math.round(tilePixelRatio * (canvasExtent[3] - originTileExtent[3]) / tileResolution)
|
||||||
|
]);
|
||||||
const tileGutter = tilePixelRatio * tileSource.getGutterForProjection(projection);
|
const tileGutter = tilePixelRatio * tileSource.getGutterForProjection(projection);
|
||||||
const tilesToDraw = tilesToDrawByZ[currentZ];
|
const tilesToDraw = tilesToDrawByZ[currentZ];
|
||||||
for (const tileCoordKey in tilesToDraw) {
|
for (const tileCoordKey in tilesToDraw) {
|
||||||
const tile = tilesToDraw[tileCoordKey];
|
const tile = tilesToDraw[tileCoordKey];
|
||||||
const tileCoord = tile.tileCoord;
|
const tileCoord = tile.tileCoord;
|
||||||
const x = originX - (originTileCoord[1] - tileCoord[1]) * w;
|
|
||||||
const y = originY + (originTileCoord[2] - tileCoord[2]) * h;
|
// Calculate integer positions and sizes so that tiles align
|
||||||
|
const floatX = (origin[0] - (originTileCoord[1] - tileCoord[1]) * dx);
|
||||||
|
const nextX = Math.round(floatX + dx);
|
||||||
|
const floatY = (origin[1] + (originTileCoord[2] - tileCoord[2]) * dy);
|
||||||
|
const nextY = Math.round(floatY + dy);
|
||||||
|
const x = Math.round(floatX);
|
||||||
|
const y = Math.round(floatY);
|
||||||
|
const w = nextX - x;
|
||||||
|
const h = nextY - y;
|
||||||
|
|
||||||
this.drawTileImage(tile, frameState, layerState, x, y, w, h, tileGutter, z === currentZ);
|
this.drawTileImage(tile, frameState, layerState, x, y, w, h, tileGutter, z === currentZ);
|
||||||
this.renderedTiles.push(tile);
|
this.renderedTiles.push(tile);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user