Image layer renderer
This commit is contained in:
@@ -3,8 +3,10 @@
|
|||||||
*/
|
*/
|
||||||
import {ENABLE_RASTER_REPROJECTION} from '../../reproj/common.js';
|
import {ENABLE_RASTER_REPROJECTION} from '../../reproj/common.js';
|
||||||
import ViewHint from '../../ViewHint.js';
|
import ViewHint from '../../ViewHint.js';
|
||||||
|
import {containsExtent, intersects} from '../../extent.js';
|
||||||
import {getIntersection, isEmpty} from '../../extent.js';
|
import {getIntersection, isEmpty} from '../../extent.js';
|
||||||
import IntermediateCanvasRenderer from './IntermediateCanvas.js';
|
import {createCanvasContext2D} from '../../dom.js';
|
||||||
|
import CanvasLayerRenderer from './Layer.js';
|
||||||
import {create as createTransform, compose as composeTransform} from '../../transform.js';
|
import {create as createTransform, compose as composeTransform} from '../../transform.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,7 +14,7 @@ import {create as createTransform, compose as composeTransform} from '../../tran
|
|||||||
* Canvas renderer for image layers.
|
* Canvas renderer for image layers.
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
|
class CanvasImageLayerRenderer extends CanvasLayerRenderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("../../layer/Image.js").default} imageLayer Image layer.
|
* @param {import("../../layer/Image.js").default} imageLayer Image layer.
|
||||||
@@ -20,6 +22,21 @@ class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
|
|||||||
constructor(imageLayer) {
|
constructor(imageLayer) {
|
||||||
super(imageLayer);
|
super(imageLayer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {CanvasRenderingContext2D}
|
||||||
|
*/
|
||||||
|
this.context = createCanvasContext2D();
|
||||||
|
|
||||||
|
const canvas = this.context.canvas;
|
||||||
|
canvas.style.position = 'absolute';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {import("../../transform.js").Transform}
|
||||||
|
*/
|
||||||
|
this.coordinateToCanvasPixelTransform = createTransform();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
* @type {?import("../../ImageBase.js").default}
|
* @type {?import("../../ImageBase.js").default}
|
||||||
@@ -52,8 +69,6 @@ class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
prepareFrame(frameState, layerState) {
|
prepareFrame(frameState, layerState) {
|
||||||
|
|
||||||
this.clear(frameState);
|
|
||||||
const pixelRatio = frameState.pixelRatio;
|
const pixelRatio = frameState.pixelRatio;
|
||||||
const size = frameState.size;
|
const size = frameState.size;
|
||||||
const viewState = frameState.viewState;
|
const viewState = frameState.viewState;
|
||||||
@@ -93,12 +108,14 @@ class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
|
|||||||
const imagePixelRatio = image.getPixelRatio();
|
const imagePixelRatio = image.getPixelRatio();
|
||||||
const scale = pixelRatio * imageResolution /
|
const scale = pixelRatio * imageResolution /
|
||||||
(viewResolution * imagePixelRatio);
|
(viewResolution * imagePixelRatio);
|
||||||
|
|
||||||
const transform = composeTransform(this.imageTransform_,
|
const transform = composeTransform(this.imageTransform_,
|
||||||
pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,
|
pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,
|
||||||
scale, scale,
|
scale, scale,
|
||||||
0,
|
0,
|
||||||
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
|
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
|
||||||
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
|
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
|
||||||
|
|
||||||
composeTransform(this.coordinateToCanvasPixelTransform,
|
composeTransform(this.coordinateToCanvasPixelTransform,
|
||||||
pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
|
pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
|
||||||
pixelRatio / viewResolution, -pixelRatio / viewResolution,
|
pixelRatio / viewResolution, -pixelRatio / viewResolution,
|
||||||
@@ -111,6 +128,64 @@ class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
|
|||||||
return !!this.image_;
|
return !!this.image_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
renderFrame(frameState, layerState) {
|
||||||
|
const pixelRatio = frameState.pixelRatio;
|
||||||
|
const context = this.context;
|
||||||
|
const canvas = context.canvas;
|
||||||
|
|
||||||
|
let width = Math.round(frameState.size[0] * pixelRatio);
|
||||||
|
let height = Math.round(frameState.size[1] * pixelRatio);
|
||||||
|
const rotation = frameState.viewState.rotation;
|
||||||
|
if (rotation) {
|
||||||
|
const size = Math.round(Math.sqrt(width * width + height * height));
|
||||||
|
width = height = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canvas.width != width || canvas.height != height) {
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
canvas.style.width = (width / pixelRatio) + 'px';
|
||||||
|
canvas.style.height = (height / pixelRatio) + 'px';
|
||||||
|
} else {
|
||||||
|
context.clearRect(0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
const image = this.image_.getImage();
|
||||||
|
|
||||||
|
// clipped rendering if layer extent is set
|
||||||
|
const extent = layerState.extent;
|
||||||
|
const clipped = extent !== undefined &&
|
||||||
|
!containsExtent(extent, frameState.extent) &&
|
||||||
|
intersects(extent, frameState.extent);
|
||||||
|
if (clipped) {
|
||||||
|
this.clip(context, frameState, extent);
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageTransform = this.getImageTransform();
|
||||||
|
|
||||||
|
// for performance reasons, context.setTransform is only used
|
||||||
|
// when the view is rotated. see http://jsperf.com/canvas-transform
|
||||||
|
const dx = imageTransform[4];
|
||||||
|
const dy = imageTransform[5];
|
||||||
|
const dw = image.width * imageTransform[0];
|
||||||
|
const dh = image.height * imageTransform[3];
|
||||||
|
|
||||||
|
if (dw >= 0.5 && dh >= 0.5) {
|
||||||
|
this.context.drawImage(image, 0, 0, +image.width, +image.height,
|
||||||
|
Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clipped) {
|
||||||
|
context.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
return canvas;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ class ImageSource extends Source {
|
|||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new ImageSourceEvent(ImageSourceEventType.IMAGELOADEND,
|
new ImageSourceEvent(ImageSourceEventType.IMAGELOADEND,
|
||||||
image));
|
image));
|
||||||
|
this.changed();
|
||||||
break;
|
break;
|
||||||
case ImageState.ERROR:
|
case ImageState.ERROR:
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user