Rotation for image layers
This commit is contained in:
@@ -42,13 +42,6 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
|
|||||||
* @type {?import("../../ImageBase.js").default}
|
* @type {?import("../../ImageBase.js").default}
|
||||||
*/
|
*/
|
||||||
this.image_ = null;
|
this.image_ = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {import("../../transform.js").Transform}
|
|
||||||
*/
|
|
||||||
this.imageTransform_ = createTransform();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,24 +51,14 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
|
|||||||
return !this.image_ ? null : this.image_.getImage();
|
return !this.image_ ? null : this.image_.getImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
getImageTransform() {
|
|
||||||
return this.imageTransform_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
prepareFrame(frameState, layerState) {
|
prepareFrame(frameState, layerState) {
|
||||||
const pixelRatio = frameState.pixelRatio;
|
const pixelRatio = frameState.pixelRatio;
|
||||||
const size = frameState.size;
|
|
||||||
const viewState = frameState.viewState;
|
const viewState = frameState.viewState;
|
||||||
const viewCenter = viewState.center;
|
|
||||||
const viewResolution = viewState.resolution;
|
const viewResolution = viewState.resolution;
|
||||||
|
|
||||||
let image;
|
|
||||||
const imageLayer = /** @type {import("../../layer/Image.js").default} */ (this.getLayer());
|
const imageLayer = /** @type {import("../../layer/Image.js").default} */ (this.getLayer());
|
||||||
const imageSource = /** @type {import("../../source/Image.js").default} */ (imageLayer.getSource());
|
const imageSource = /** @type {import("../../source/Image.js").default} */ (imageLayer.getSource());
|
||||||
|
|
||||||
@@ -86,8 +69,7 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
|
|||||||
renderedExtent = getIntersection(renderedExtent, layerState.extent);
|
renderedExtent = getIntersection(renderedExtent, layerState.extent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hints[ViewHint.ANIMATING] && !hints[ViewHint.INTERACTING] &&
|
if (!hints[ViewHint.ANIMATING] && !hints[ViewHint.INTERACTING] && !isEmpty(renderedExtent)) {
|
||||||
!isEmpty(renderedExtent)) {
|
|
||||||
let projection = viewState.projection;
|
let projection = viewState.projection;
|
||||||
if (!ENABLE_RASTER_REPROJECTION) {
|
if (!ENABLE_RASTER_REPROJECTION) {
|
||||||
const sourceProjection = imageSource.getProjection();
|
const sourceProjection = imageSource.getProjection();
|
||||||
@@ -101,30 +83,6 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.image_) {
|
|
||||||
image = this.image_;
|
|
||||||
const imageExtent = image.getExtent();
|
|
||||||
const imageResolution = image.getResolution();
|
|
||||||
const imagePixelRatio = image.getPixelRatio();
|
|
||||||
const scale = pixelRatio * imageResolution /
|
|
||||||
(viewResolution * imagePixelRatio);
|
|
||||||
|
|
||||||
const transform = composeTransform(this.imageTransform_,
|
|
||||||
pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,
|
|
||||||
scale, scale,
|
|
||||||
0,
|
|
||||||
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
|
|
||||||
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
|
|
||||||
|
|
||||||
composeTransform(this.coordinateToCanvasPixelTransform,
|
|
||||||
pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
|
|
||||||
pixelRatio / viewResolution, -pixelRatio / viewResolution,
|
|
||||||
0,
|
|
||||||
-viewCenter[0], -viewCenter[1]);
|
|
||||||
|
|
||||||
this.renderedResolution = imageResolution * pixelRatio / imagePixelRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
return !!this.image_;
|
return !!this.image_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,18 +90,45 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
renderFrame(frameState, layerState) {
|
renderFrame(frameState, layerState) {
|
||||||
|
const image = this.image_;
|
||||||
|
const imageExtent = image.getExtent();
|
||||||
|
const imageResolution = image.getResolution();
|
||||||
|
const imagePixelRatio = image.getPixelRatio();
|
||||||
const pixelRatio = frameState.pixelRatio;
|
const pixelRatio = frameState.pixelRatio;
|
||||||
const context = this.context;
|
const viewState = frameState.viewState;
|
||||||
const canvas = context.canvas;
|
const viewCenter = viewState.center;
|
||||||
|
const viewResolution = viewState.resolution;
|
||||||
|
const size = frameState.size;
|
||||||
|
const scale = pixelRatio * imageResolution / (viewResolution * imagePixelRatio);
|
||||||
|
|
||||||
let width = Math.round(frameState.size[0] * pixelRatio);
|
let width = Math.round(size[0] * pixelRatio);
|
||||||
let height = Math.round(frameState.size[1] * pixelRatio);
|
let height = Math.round(size[1] * pixelRatio);
|
||||||
const rotation = frameState.viewState.rotation;
|
const rotation = viewState.rotation;
|
||||||
if (rotation) {
|
if (rotation) {
|
||||||
const size = Math.round(Math.sqrt(width * width + height * height));
|
const size = Math.round(Math.sqrt(width * width + height * height));
|
||||||
width = height = size;
|
width = height = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const transform = composeTransform(this.transform_,
|
||||||
|
width / 2, height / 2,
|
||||||
|
scale, scale,
|
||||||
|
0,
|
||||||
|
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
|
||||||
|
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
|
||||||
|
|
||||||
|
composeTransform(this.coordinateToCanvasPixelTransform,
|
||||||
|
pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
|
||||||
|
pixelRatio / viewResolution, -pixelRatio / viewResolution,
|
||||||
|
0,
|
||||||
|
-viewCenter[0], -viewCenter[1]);
|
||||||
|
|
||||||
|
this.renderedResolution = imageResolution * pixelRatio / imagePixelRatio;
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
canvas.height = height;
|
canvas.height = height;
|
||||||
@@ -153,8 +138,6 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
|
|||||||
context.clearRect(0, 0, width, height);
|
context.clearRect(0, 0, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
const image = this.image_.getImage();
|
|
||||||
|
|
||||||
// clipped rendering if layer extent is set
|
// clipped rendering if layer extent is set
|
||||||
const extent = layerState.extent;
|
const extent = layerState.extent;
|
||||||
const clipped = extent !== undefined &&
|
const clipped = extent !== undefined &&
|
||||||
@@ -164,17 +147,15 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
|
|||||||
this.clip(context, frameState, extent);
|
this.clip(context, frameState, extent);
|
||||||
}
|
}
|
||||||
|
|
||||||
const imageTransform = this.getImageTransform();
|
const img = image.getImage();
|
||||||
|
|
||||||
// for performance reasons, context.setTransform is only used
|
const dx = transform[4];
|
||||||
// when the view is rotated. see http://jsperf.com/canvas-transform
|
const dy = transform[5];
|
||||||
const dx = imageTransform[4];
|
const dw = img.width * transform[0];
|
||||||
const dy = imageTransform[5];
|
const dh = img.height * transform[3];
|
||||||
const dw = image.width * imageTransform[0];
|
|
||||||
const dh = image.height * imageTransform[3];
|
|
||||||
|
|
||||||
if (dw >= 0.5 && dh >= 0.5) {
|
if (dw >= 0.5 && dh >= 0.5) {
|
||||||
this.context.drawImage(image, 0, 0, +image.width, +image.height,
|
this.context.drawImage(img, 0, 0, +img.width, +img.height,
|
||||||
Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));
|
Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,6 +163,11 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
|
|||||||
context.restore();
|
context.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const canvasTransform = 'rotate(' + rotation + 'rad)';
|
||||||
|
if (canvasTransform !== canvas.style.transform) {
|
||||||
|
canvas.style.transform = canvasTransform;
|
||||||
|
}
|
||||||
|
|
||||||
return canvas;
|
return canvas;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -377,13 +377,6 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
|||||||
return context ? context.canvas : null;
|
return context ? context.canvas : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
getImageTransform() {
|
|
||||||
return this.imageTransform_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the image from a tile.
|
* Get the image from a tile.
|
||||||
* @param {import("../../Tile.js").default} tile Tile.
|
* @param {import("../../Tile.js").default} tile Tile.
|
||||||
|
|||||||
Reference in New Issue
Block a user