diff --git a/packages/maptalks/src/renderer/layer/CanvasRenderer.ts b/packages/maptalks/src/renderer/layer/CanvasRenderer.ts index 26e2dcc802..8dfbcc1b6f 100644 --- a/packages/maptalks/src/renderer/layer/CanvasRenderer.ts +++ b/packages/maptalks/src/renderer/layer/CanvasRenderer.ts @@ -169,8 +169,9 @@ class CanvasRenderer extends LayerAbstractRenderer { if (!canvas) { return; } - const size = canvasSize || this.getMap().getSize(); - const r = this.getMap().getDevicePixelRatio(); + const map = this.getMap(); + const size = canvasSize || map.getSize(); + const r = map.getDevicePixelRatio(); const { width, height, cssWidth, cssHeight } = calCanvasSize(size, r); // width/height不变并不意味着 css width/height 不变 if (this.layer._canvas && (canvas.style.width !== cssWidth || canvas.style.height !== cssHeight)) { @@ -196,11 +197,15 @@ class CanvasRenderer extends LayerAbstractRenderer { * Clear the canvas to blank */ clearCanvas(): void { - if (!this.context || !this.getMap()) { + if (!this.context) { + return; + } + const map = this.getMap(); + if (!map) { return; } //fix #1597 - const r = this.getMap().getDevicePixelRatio(); + const r = this.mapDPR || map.getDevicePixelRatio(); const rScale = 1 / r; const w = this.canvas.width * rScale, h = this.canvas.height * rScale; Canvas2D.clearRect(this.context, 0, 0, Math.max(w, this.canvas.width), Math.max(h, this.canvas.height)); @@ -287,7 +292,7 @@ class CanvasRenderer extends LayerAbstractRenderer { //geometry 渲染逻辑里会修改globalAlpha,这里保存一下 const alpha = context.globalAlpha; context.save(); - const dpr = map.getDevicePixelRatio(); + const dpr = this.mapDPR || map.getDevicePixelRatio(); if (dpr !== 1) { context.save(); this._canvasContextScale(context, dpr); diff --git a/packages/maptalks/src/renderer/layer/ImageGLRenderable.ts b/packages/maptalks/src/renderer/layer/ImageGLRenderable.ts index 102dd223bc..63ecf18f09 100644 --- a/packages/maptalks/src/renderer/layer/ImageGLRenderable.ts +++ b/packages/maptalks/src/renderer/layer/ImageGLRenderable.ts @@ -126,6 +126,7 @@ const ImageGLRenderable = function (Base: T) { v3[1] = y || 0; v3[2] = 0; const layer = this.layer; + const map = this.getMap(); if (layer) { const { altitude } = layer.options; const altIsNumber = isNumber(altitude); @@ -134,19 +135,16 @@ const ImageGLRenderable = function (Base: T) { } //update _layerAlt cache if (this._layerAltitude !== altitude && altIsNumber) { - const map = layer.getMap(); - if (map) { - const z = map.altitudeToPoint(altitude, map.getGLRes()); - this._layerAltitude = altitude; - this._layerAlt = z; - } + const z = map.altitudeToPoint(altitude, map.getGLRes()); + this._layerAltitude = altitude; + this._layerAlt = z; } } v3[2] = this._layerAlt || 0; const uMatrix = mat4.identity(arr16); mat4.translate(uMatrix, uMatrix, v3); mat4.scale(uMatrix, uMatrix, [scale, scale, 1]); - mat4.multiply(uMatrix, this.getMap().projViewMatrix, uMatrix); + mat4.multiply(uMatrix, map.projViewMatrix, uMatrix); gl.uniformMatrix4fv(this.program['u_matrix'], false, uMatrix); gl.uniform1f(this.program['u_opacity'], opacity); gl.uniform1f(this.program['u_debug_line'], 0); @@ -210,7 +208,7 @@ const ImageGLRenderable = function (Base: T) { //draw debug info let canvas = this._debugInfoCanvas; if (!canvas) { - const dpr = (this as any).getMap().getDevicePixelRatio() > 1 ? 2 : 1; + const dpr = (this as any).mapDPR || (this as any).getMap().getDevicePixelRatio() > 1 ? 2 : 1; canvas = this._debugInfoCanvas = document.createElement('canvas'); canvas.width = 256 * dpr; canvas.height = 32 * dpr; @@ -428,7 +426,7 @@ const ImageGLRenderable = function (Base: T) { const genMipmap = this.layer.options['mipmapTexture']; if (genMipmap) { const map = (this as any).getMap(); - const dpr = map.getDevicePixelRatio(); + const dpr = (this as any).mapDPR || map.getDevicePixelRatio(); if (map.isMoving() && map.getRenderer().isViewChanged()) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); } else { diff --git a/packages/maptalks/src/renderer/layer/LayerAbstractRenderer.ts b/packages/maptalks/src/renderer/layer/LayerAbstractRenderer.ts index 5cce9bbd65..2e311be1a5 100644 --- a/packages/maptalks/src/renderer/layer/LayerAbstractRenderer.ts +++ b/packages/maptalks/src/renderer/layer/LayerAbstractRenderer.ts @@ -70,6 +70,7 @@ class LayerAbstractRenderer extends Class { _errorThrown: boolean; //@internal __zoomTransformMatrix: number[]; + mapDPR?: number; drawOnInteracting?(...args: any[]): void; checkResources?(): any[]; @@ -341,7 +342,7 @@ class LayerAbstractRenderer extends Class { return false; } const map = this.getMap(); - const r = map.getDevicePixelRatio(); + const r = this.mapDPR || map.getDevicePixelRatio(); const size = map.getSize(); if (point.x < 0 || point.x > size['width'] * r || point.y < 0 || point.y > size['height'] * r) { return false; @@ -634,12 +635,16 @@ class LayerAbstractRenderer extends Class { //@internal _drawAndRecord(framestamp: number) { - if (!this.getMap()) { + const map = this.getMap(); + if (!map) { return; } const painted = this._painted; this._painted = true; let t = now(); + + this.mapDPR = map.getDevicePixelRatio(); + this.draw(framestamp); t = now() - t; //reduce some time in the first draw diff --git a/packages/maptalks/src/renderer/layer/tilelayer/TileLayerCanvasRenderer.ts b/packages/maptalks/src/renderer/layer/tilelayer/TileLayerCanvasRenderer.ts index 4aecb13f1e..3b4f0f3f98 100644 --- a/packages/maptalks/src/renderer/layer/tilelayer/TileLayerCanvasRenderer.ts +++ b/packages/maptalks/src/renderer/layer/tilelayer/TileLayerCanvasRenderer.ts @@ -167,15 +167,18 @@ export default class TileLayerCanvasRenderer extends TileLayerRenderable(CanvasR // eslint-disable-next-line @typescript-eslint/no-unused-vars drawTile(tileInfo: Tile['info'], tileImage: Tile['image'], parentContext?: RenderContext) { - if (!tileImage || !this.getMap()) { + if (!tileImage) { + return; + } + const map = this.getMap(); + if (!map) { return; } const { extent2d, offset } = tileInfo; const point = TILE_POINT.set(extent2d.xmin - offset[0], extent2d.ymax - offset[1]), tileZoom = tileInfo.z, tileId = tileInfo.id; - const map = this.getMap(), - zoom = map.getZoom(), + const zoom = map.getZoom(), ctx = this.context, cp = map._pointAtResToContainerPoint(point, tileInfo.res, 0, TEMP_POINT), bearing = map.getBearing(), diff --git a/packages/maptalks/src/renderer/layer/tilelayer/TileLayerGLRenderer.ts b/packages/maptalks/src/renderer/layer/tilelayer/TileLayerGLRenderer.ts index dec75e1a99..928c0f13a9 100644 --- a/packages/maptalks/src/renderer/layer/tilelayer/TileLayerGLRenderer.ts +++ b/packages/maptalks/src/renderer/layer/tilelayer/TileLayerGLRenderer.ts @@ -7,7 +7,7 @@ import { SizeLike } from '../../../geo/Size'; const TILE_POINT = new Point(0, 0); -const MESH_TO_TEST = { properties: {}}; +const MESH_TO_TEST = { properties: {} }; /** * 基于 HTML5 WebGL 的 TileLayers 渲染器 @@ -93,7 +93,7 @@ class TileLayerGLRenderer extends ImageGLRenderable(TileLayerCanvasRenderer) { const opacity = this.getTileOpacity(tileImage, tileInfo); let debugInfo = null; if (this.layer.options['debug']) { - debugInfo = this.getDebugInfo(tileInfo.id); + debugInfo = this.getDebugInfo(tileInfo.id); } const gl = this.gl; gl.stencilFunc(gl.LEQUAL, Math.abs(this.getCurrentTileZoom() - tileInfo.z), 0xFF); @@ -116,7 +116,7 @@ class TileLayerGLRenderer extends ImageGLRenderable(TileLayerCanvasRenderer) { } } - loadTileImage(tileImage: HTMLImageElement, url: string) { + loadTileImage(tileImage: HTMLImageElement, url: string, tile: Tile['info']): void { // image must set cors in webgl const crossOrigin = this.layer.options['crossOrigin']; tileImage.crossOrigin = crossOrigin !== null ? crossOrigin : ''; diff --git a/packages/maptalks/src/renderer/layer/tilelayer/TileLayerRendererable.ts b/packages/maptalks/src/renderer/layer/tilelayer/TileLayerRendererable.ts index 65e6d1fbc6..0ecc715ccd 100644 --- a/packages/maptalks/src/renderer/layer/tilelayer/TileLayerRendererable.ts +++ b/packages/maptalks/src/renderer/layer/tilelayer/TileLayerRendererable.ts @@ -632,7 +632,7 @@ const TileLayerRenderable = function (Base: T) { (tileImage as any).onload = this.onTileLoad.bind(this, tileImage, tile); (tileImage as any).onerror = this.onTileError.bind(this, tileImage, tile); - this.loadTileImage(tileImage, tile['url']); + this.loadTileImage(tileImage, tile['url'], tile); } return tileImage; } @@ -659,7 +659,7 @@ const TileLayerRenderable = function (Base: T) { } } - loadTileImage(tileImage, url: string) { + loadTileImage(tileImage, url: string, tile: Tile['info']) { const crossOrigin = this.layer.options['crossOrigin']; if (!isNil(crossOrigin)) { tileImage.crossOrigin = crossOrigin; diff --git a/packages/maptalks/src/renderer/layer/vectorlayer/VectorLayerCanvasRenderer.ts b/packages/maptalks/src/renderer/layer/vectorlayer/VectorLayerCanvasRenderer.ts index 1142361b7c..a40bfbda8b 100644 --- a/packages/maptalks/src/renderer/layer/vectorlayer/VectorLayerCanvasRenderer.ts +++ b/packages/maptalks/src/renderer/layer/vectorlayer/VectorLayerCanvasRenderer.ts @@ -757,7 +757,7 @@ class VectorLayerRenderer extends OverlayLayerCanvasRenderer { if (!map) { return this; } - const dpr = map.getDevicePixelRatio() || 1; + const dpr = this.mapDPR || map.getDevicePixelRatio() || 1; const rScale = 1 / dpr; this._canvasContextScale(context, rScale); context.drawImage(snapshotCanvas, 0, 0); diff --git a/packages/maptalks/src/renderer/map/MapAbstractRenderer.ts b/packages/maptalks/src/renderer/map/MapAbstractRenderer.ts index 9f84828a5e..7138b9f51b 100644 --- a/packages/maptalks/src/renderer/map/MapAbstractRenderer.ts +++ b/packages/maptalks/src/renderer/map/MapAbstractRenderer.ts @@ -628,13 +628,13 @@ class MapAbstractRenderer extends MapRenderer { //@internal _updateDomPosition(framestamp: number) { if (this._checkPositionTime === undefined) { - this._checkPositionTime = -Infinity; + this._checkPositionTime = 0; } const dTime = Math.abs(framestamp - this._checkPositionTime); if (dTime >= 500) { // refresh map's dom position computeDomPosition(this.map.getContainer()); - this._checkPositionTime = Math.min(framestamp, this._checkPositionTime); + this._checkPositionTime = framestamp; } return this; }