Make forward and inverse pixel transforms during render

This commit is contained in:
Tim Schaub
2018-11-17 14:46:38 +01:00
parent db1f432197
commit 686847f491
5 changed files with 46 additions and 18 deletions

View File

@@ -6,7 +6,7 @@ import ViewHint from '../../ViewHint.js';
import {containsExtent, intersects} from '../../extent.js'; import {containsExtent, intersects} from '../../extent.js';
import {getIntersection, isEmpty} from '../../extent.js'; import {getIntersection, isEmpty} from '../../extent.js';
import CanvasLayerRenderer from './Layer.js'; import CanvasLayerRenderer from './Layer.js';
import {compose as composeTransform, toString as transformToString} from '../../transform.js'; import {compose as composeTransform, makeInverse, toString as transformToString} from '../../transform.js';
/** /**
* @classdesc * @classdesc
@@ -93,16 +93,17 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
width = height = size; width = height = size;
} }
const context = this.context; // set forward and inverse pixel transforms
const canvas = context.canvas; composeTransform(this.pixelTransform_,
const pixelTransform = composeTransform(this.pixelTransform_,
frameState.size[0] / 2, frameState.size[1] / 2, frameState.size[0] / 2, frameState.size[1] / 2,
1 / pixelRatio, 1 / pixelRatio, 1 / pixelRatio, 1 / pixelRatio,
rotation, rotation,
-width / 2, -height / 2 -width / 2, -height / 2
); );
const canvasTransform = transformToString(pixelTransform); makeInverse(this.pixelTransform_, this.inversePixelTransform_);
const context = this.context;
const canvas = context.canvas;
if (canvas.width != width || canvas.height != height) { if (canvas.width != width || canvas.height != height) {
canvas.width = width; canvas.width = width;
@@ -150,6 +151,7 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
canvas.style.opacity = opacity; canvas.style.opacity = opacity;
} }
const canvasTransform = transformToString(this.pixelTransform_);
if (canvasTransform !== canvas.style.transform) { if (canvasTransform !== canvas.style.transform) {
canvas.style.transform = canvasTransform; canvas.style.transform = canvasTransform;
} }

View File

@@ -28,19 +28,29 @@ class CanvasLayerRenderer extends LayerRenderer {
this.renderedResolution; this.renderedResolution;
/** /**
* A temporary transform. * A temporary transform. The values in this transform should only be used in a
* function that sets the values.
* @private * @private
* @type {import("../../transform.js").Transform} * @type {import("../../transform.js").Transform}
*/ */
this.tempTransform_ = createTransform(); this.tempTransform_ = createTransform();
/** /**
* The transform for rendered pixels to viewport CSS pixels. * The transform for rendered pixels to viewport CSS pixels. This transform must
* be set when rendering a frame and may be used by other functions after rendering.
* @private * @private
* @type {import("../../transform.js").Transform} * @type {import("../../transform.js").Transform}
*/ */
this.pixelTransform_ = createTransform(); this.pixelTransform_ = createTransform();
/**
* The transform for viewport CSS pixels to rendered pixels. This transform must
* be set when rendering a frame and may be used by other functions after rendering.
* @private
* @type {import("../../transform.js").Transform}
*/
this.inversePixelTransform_ = createTransform();
/** /**
* @protected * @protected
* @type {CanvasRenderingContext2D} * @type {CanvasRenderingContext2D}

View File

@@ -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, toString as transformToString} from '../../transform.js'; import {compose as composeTransform, makeInverse, toString as transformToString} from '../../transform.js';
/** /**
* @classdesc * @classdesc
@@ -222,15 +222,18 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
} }
} }
const canvas = context.canvas; const canvas = context.canvas;
const canvasScale = tileResolution / frameState.viewState.resolution / tilePixelRatio; const canvasScale = tileResolution / frameState.viewState.resolution / tilePixelRatio;
const pixelTransform = composeTransform(this.pixelTransform_,
// set forward and inverse pixel transforms
composeTransform(this.pixelTransform_,
frameState.size[0] / 2, frameState.size[1] / 2, frameState.size[0] / 2, frameState.size[1] / 2,
canvasScale, canvasScale, canvasScale, canvasScale,
rotation, rotation,
-width / 2, -height / 2 -width / 2, -height / 2
); );
const canvasTransform = transformToString(pixelTransform); makeInverse(this.pixelTransform_, this.inversePixelTransform_);
if (canvas.width != width || canvas.height != height) { if (canvas.width != width || canvas.height != height) {
canvas.width = width; canvas.width = width;
@@ -302,6 +305,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
canvas.style.opacity = opacity; canvas.style.opacity = opacity;
} }
const canvasTransform = transformToString(this.pixelTransform_);
if (canvasTransform !== canvas.style.transform) { if (canvasTransform !== canvas.style.transform) {
canvas.style.transform = canvasTransform; canvas.style.transform = canvasTransform;
} }

View File

@@ -13,7 +13,7 @@ import CanvasBuilderGroup from '../../render/canvas/BuilderGroup.js';
import InstructionsGroupExecutor from '../../render/canvas/ExecutorGroup.js'; import InstructionsGroupExecutor from '../../render/canvas/ExecutorGroup.js';
import CanvasLayerRenderer from './Layer.js'; import CanvasLayerRenderer from './Layer.js';
import {defaultOrder as defaultRenderOrder, getTolerance as getRenderTolerance, getSquaredTolerance as getSquaredRenderTolerance, renderFeature} from '../vector.js'; import {defaultOrder as defaultRenderOrder, getTolerance as getRenderTolerance, getSquaredTolerance as getSquaredRenderTolerance, renderFeature} from '../vector.js';
import {toString as transformToString} from '../../transform.js'; import {toString as transformToString, makeScale, makeInverse} from '../../transform.js';
/** /**
* @classdesc * @classdesc
@@ -105,8 +105,9 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
const pixelRatio = frameState.pixelRatio; const pixelRatio = frameState.pixelRatio;
// a scale transform (we could add a createScale function in ol/transform) // set forward and inverse pixel transforms
const pixelTransform = [1 / pixelRatio, 0, 0, 1 / pixelRatio, 0, 0]; makeScale(this.pixelTransform_, 1 / pixelRatio, 1 / pixelRatio);
makeInverse(this.pixelTransform_, this.inversePixelTransform_);
// resize and clear // resize and clear
const width = Math.round(frameState.size[0] * pixelRatio); const width = Math.round(frameState.size[0] * pixelRatio);
@@ -114,7 +115,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
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;
const canvasTransform = transformToString(pixelTransform); const canvasTransform = transformToString(this.pixelTransform_);
if (canvas.style.transform !== canvasTransform) { if (canvas.style.transform !== canvasTransform) {
canvas.style.transform = canvasTransform; canvas.style.transform = canvasTransform;
} }

View File

@@ -26,7 +26,9 @@ import {
reset as resetTransform, reset as resetTransform,
scale as scaleTransform, scale as scaleTransform,
translate as translateTransform, translate as translateTransform,
toString as transformToString toString as transformToString,
makeScale,
makeInverse
} from '../../transform.js'; } from '../../transform.js';
import CanvasExecutorGroup, {replayDeclutter} from '../../render/canvas/ExecutorGroup.js'; import CanvasExecutorGroup, {replayDeclutter} from '../../render/canvas/ExecutorGroup.js';
@@ -98,6 +100,13 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
*/ */
this.overlayPixelTransform_ = createTransform(); this.overlayPixelTransform_ = createTransform();
/**
* The transform for viewport CSS pixels to rendered pixels for the overlay canvas.
* @private
* @type {import("../../transform.js").Transform}
*/
this.inverseOverlayPixelTransform_ = createTransform();
/** /**
* Declutter tree. * Declutter tree.
* @private * @private
@@ -384,12 +393,14 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
const rotation = frameState.viewState.rotation; const rotation = frameState.viewState.rotation;
const size = frameState.size; const size = frameState.size;
// set forward and inverse pixel transforms
makeScale(this.overlayPixelTransform_, 1 / pixelRatio, 1 / pixelRatio);
makeInverse(this.overlayPixelTransform_, this.inverseOverlayPixelTransform_);
// resize and clear // resize and clear
const canvas = context.canvas; const canvas = context.canvas;
const width = Math.round(size[0] * pixelRatio); const width = Math.round(size[0] * pixelRatio);
const height = Math.round(size[1] * pixelRatio); const height = Math.round(size[1] * pixelRatio);
this.overlayPixelTransform_[0] = 1 / pixelRatio;
this.overlayPixelTransform_[3] = 1 / pixelRatio;
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;