From 2a6979e15a5c1efd1f93d73ca214b5520c84fd6a Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 19 Dec 2013 16:25:57 +0100 Subject: [PATCH 1/7] ol.style.Image rotation is always defined --- src/ol/style/imagestyle.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ol/style/imagestyle.js b/src/ol/style/imagestyle.js index ddb5089401..9ed3d1b4b4 100644 --- a/src/ol/style/imagestyle.js +++ b/src/ol/style/imagestyle.js @@ -53,7 +53,7 @@ ol.style.Image = function(options) { /** * @private - * @type {number|undefined} + * @type {number} */ this.rotation_ = options.rotation; @@ -104,7 +104,7 @@ ol.style.Image.prototype.getImageState = function() { /** - * @return {number|undefined} Rotation. + * @return {number} Rotation. */ ol.style.Image.prototype.getRotation = function() { return this.rotation_; From 9524a46f41899e0f437541d2f1027f719974e074 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 19 Dec 2013 15:28:15 +0100 Subject: [PATCH 2/7] Add scale to ol.style.Image --- src/ol/style/circlestyle.js | 1 + src/ol/style/imagestyle.js | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/ol/style/circlestyle.js b/src/ol/style/circlestyle.js index c698f46247..98b2c0a48b 100644 --- a/src/ol/style/circlestyle.js +++ b/src/ol/style/circlestyle.js @@ -52,6 +52,7 @@ ol.style.Circle = function(opt_options) { anchor: [size / 2, size / 2], imageState: ol.style.ImageState.LOADED, rotation: 0, + scale: 1, size: [size, size], snapToPixel: undefined, subtractViewRotation: false diff --git a/src/ol/style/imagestyle.js b/src/ol/style/imagestyle.js index 9ed3d1b4b4..4491030da5 100644 --- a/src/ol/style/imagestyle.js +++ b/src/ol/style/imagestyle.js @@ -22,6 +22,7 @@ ol.style.ImageState = { * @typedef {{anchor: ol.Pixel, * imageState: ol.style.ImageState, * rotation: number, + * scale: number, * size: ol.Size, * snapToPixel: (boolean|undefined), * subtractViewRotation: boolean}} @@ -57,6 +58,12 @@ ol.style.Image = function(options) { */ this.rotation_ = options.rotation; + /** + * @private + * @type {number} + */ + this.scale_ = options.scale; + /** * @protected * @type {ol.Size} @@ -111,6 +118,14 @@ ol.style.Image.prototype.getRotation = function() { }; +/** + * @return {number} Scale. + */ +ol.style.Image.prototype.getScale = function() { + return this.scale_; +}; + + /** * @return {ol.Size} Size. */ From d82f1f8e02bbd14737a6a98e97edb2343d1fb3a0 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 19 Dec 2013 15:28:44 +0100 Subject: [PATCH 3/7] Add scale to ol.style.IconStyle --- src/objectliterals.jsdoc | 1 + src/ol/style/iconstyle.js | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 959f6a2349..0c3e6aaa76 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -735,6 +735,7 @@ * @typedef {Object} olx.style.IconOptions * @property {ol.Pixel|undefined} anchor Anchor. * @property {null|string|undefined} crossOrigin crossOrigin setting for image. + * @property {number|undefined} scale Scale. * @property {number|undefined} rotation Rotation. * @property {ol.Size|undefined} size Icon size in pixel. * @property {string} src Image source URI. diff --git a/src/ol/style/iconstyle.js b/src/ol/style/iconstyle.js index 96b312ee92..c4df241a40 100644 --- a/src/ol/style/iconstyle.js +++ b/src/ol/style/iconstyle.js @@ -83,10 +83,16 @@ ol.style.Icon = function(opt_options) { */ var rotation = goog.isDef(options.rotation) ? options.rotation : 0; + /** + * @type {number} + */ + var scale = goog.isDef(options.scale) ? options.scale : 1; + goog.base(this, { anchor: anchor, imageState: ol.style.ImageState.IDLE, rotation: rotation, + scale: scale, size: size, snapToPixel: undefined, subtractViewRotation: false From c6b961782a4e2ae41536d71bba8d6028eeb2bea3 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 19 Dec 2013 15:31:46 +0100 Subject: [PATCH 4/7] Sort miscellaneous properties and add rotation and scale --- src/ol/render/canvas/canvasreplay.js | 91 ++++++++++++++++++---------- 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/src/ol/render/canvas/canvasreplay.js b/src/ol/render/canvas/canvasreplay.js index 8a72a97353..44db0b2e01 100644 --- a/src/ol/render/canvas/canvasreplay.js +++ b/src/ol/render/canvas/canvasreplay.js @@ -202,13 +202,16 @@ ol.render.canvas.Replay.prototype.replay_ = d = /** @type {number} */ (instruction[1]); goog.asserts.assert(goog.isNumber(instruction[2])); dd = /** @type {number} */ (instruction[2]); - var anchorX = /** @type {number} */ (instruction[3]); - var anchorY = /** @type {number} */ (instruction[4]); - var width = /** @type {number} */ (instruction[5]); - var height = /** @type {number} */ (instruction[6]); var image = /** @type {HTMLCanvasElement|HTMLVideoElement|Image} */ - (instruction[7]); - var snapToPixel = /** @type {boolean|undefined} */ (instruction[8]); + (instruction[3]); + // Remaining arguments in DRAW_IMAGE are in alphabetical order + var anchorX = /** @type {number} */ (instruction[4]); + var anchorY = /** @type {number} */ (instruction[5]); + var height = /** @type {number} */ (instruction[6]); + var rotation = /** @type {number} */ (instruction[7]); + var scale = /** @type {number} */ (instruction[8]); + var snapToPixel = /** @type {boolean|undefined} */ (instruction[9]); + var width = /** @type {number} */ (instruction[10]); for (; d < dd; d += 2) { var x = pixelCoordinates[d] - anchorX; var y = pixelCoordinates[d + 1] - anchorY; @@ -454,18 +457,6 @@ ol.render.canvas.ImageReplay = function(pixelRatio, tolerance) { goog.base(this, pixelRatio, tolerance); - /** - * @private - * @type {number|undefined} - */ - this.anchorX_ = undefined; - - /** - * @private - * @type {number|undefined} - */ - this.anchorY_ = undefined; - /** * @private * @type {HTMLCanvasElement|HTMLVideoElement|Image} @@ -478,6 +469,18 @@ ol.render.canvas.ImageReplay = function(pixelRatio, tolerance) { */ this.image_ = null; + /** + * @private + * @type {number|undefined} + */ + this.anchorX_ = undefined; + + /** + * @private + * @type {number|undefined} + */ + this.anchorY_ = undefined; + /** * @private * @type {number|undefined} @@ -488,7 +491,13 @@ ol.render.canvas.ImageReplay = function(pixelRatio, tolerance) { * @private * @type {number|undefined} */ - this.width_ = undefined; + this.rotation_ = undefined; + + /** + * @private + * @type {number|undefined} + */ + this.scale_ = undefined; /** * @private @@ -496,6 +505,12 @@ ol.render.canvas.ImageReplay = function(pixelRatio, tolerance) { */ this.snapToPixel_ = undefined; + /** + * @private + * @type {number|undefined} + */ + this.width_ = undefined; + }; goog.inherits(ol.render.canvas.ImageReplay, ol.render.canvas.Replay); @@ -526,6 +541,8 @@ ol.render.canvas.ImageReplay.prototype.drawPointGeometry = goog.asserts.assert(goog.isDef(this.anchorX_)); goog.asserts.assert(goog.isDef(this.anchorY_)); goog.asserts.assert(goog.isDef(this.height_)); + goog.asserts.assert(goog.isDef(this.rotation_)); + goog.asserts.assert(goog.isDef(this.scale_)); goog.asserts.assert(goog.isDef(this.width_)); ol.extent.extend(this.extent_, pointGeometry.getExtent()); this.beginGeometry(pointGeometry); @@ -535,14 +552,17 @@ ol.render.canvas.ImageReplay.prototype.drawPointGeometry = var myEnd = this.drawCoordinates_( flatCoordinates, 0, flatCoordinates.length, stride); this.instructions.push([ - ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, - this.anchorX_, this.anchorY_, this.width_, this.height_, - this.image_, this.snapToPixel_ + ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, this.image_, + // Remaining arguments to DRAW_IMAGE are in alphabetical order + this.anchorX_, this.anchorY_, this.height_, this.rotation_, this.scale_, + this.snapToPixel_, this.width_ ]); this.hitDetectionInstructions.push([ ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, - this.anchorX_, this.anchorY_, this.width_, this.height_, - this.hitDetectionImage_, this.snapToPixel_ + this.hitDetectionImage_, + // Remaining arguments to DRAW_IMAGE are in alphabetical order + this.anchorX_, this.anchorY_, this.height_, this.rotation_, this.scale_, + this.snapToPixel_, this.width_ ]); this.endGeometry(pointGeometry, data); }; @@ -559,6 +579,8 @@ ol.render.canvas.ImageReplay.prototype.drawMultiPointGeometry = goog.asserts.assert(goog.isDef(this.anchorX_)); goog.asserts.assert(goog.isDef(this.anchorY_)); goog.asserts.assert(goog.isDef(this.height_)); + goog.asserts.assert(goog.isDef(this.rotation_)); + goog.asserts.assert(goog.isDef(this.scale_)); goog.asserts.assert(goog.isDef(this.width_)); ol.extent.extend(this.extent_, multiPointGeometry.getExtent()); this.beginGeometry(multiPointGeometry); @@ -568,14 +590,17 @@ ol.render.canvas.ImageReplay.prototype.drawMultiPointGeometry = var myEnd = this.drawCoordinates_( flatCoordinates, 0, flatCoordinates.length, stride); this.instructions.push([ - ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, - this.anchorX_, this.anchorY_, this.width_, this.height_, - this.image_, this.snapToPixel_ + ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, this.image_, + // Remaining arguments to DRAW_IMAGE are in alphabetical order + this.anchorX_, this.anchorY_, this.height_, this.rotation_, this.scale_, + this.snapToPixel_, this.width_ ]); this.hitDetectionInstructions.push([ ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, - this.anchorX_, this.anchorY_, this.width_, this.height_, - this.hitDetectionImage_, this.snapToPixel_ + this.hitDetectionImage_, + // Remaining arguments to DRAW_IMAGE are in alphabetical order + this.anchorX_, this.anchorY_, this.height_, this.rotation_, this.scale_, + this.snapToPixel_, this.width_ ]); this.endGeometry(multiPointGeometry, data); }; @@ -592,8 +617,10 @@ ol.render.canvas.ImageReplay.prototype.finish = function() { this.hitDetectionImage_ = null; this.image_ = null; this.height_ = undefined; - this.width_ = undefined; + this.scale_ = undefined; + this.rotation_ = undefined; this.snapToPixel_ = undefined; + this.width_ = undefined; }; @@ -615,9 +642,11 @@ ol.render.canvas.ImageReplay.prototype.setImageStyle = function(imageStyle) { this.anchorY_ = anchor[1]; this.hitDetectionImage_ = hitDetectionImage; this.image_ = image; - this.width_ = size[0]; this.height_ = size[1]; + this.rotation_ = imageStyle.getRotation(); + this.scale_ = imageStyle.getScale(); this.snapToPixel_ = imageStyle.getSnapToPixel(); + this.width_ = size[0]; }; From b3f77b4d68e6d4c9394cf128e8b56854d6daa72b Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 19 Dec 2013 15:32:08 +0100 Subject: [PATCH 5/7] Add image rotation and scaling to ol.render.canvas.Replay --- src/ol/render/canvas/canvasreplay.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/ol/render/canvas/canvasreplay.js b/src/ol/render/canvas/canvasreplay.js index 44db0b2e01..9a63c29df4 100644 --- a/src/ol/render/canvas/canvasreplay.js +++ b/src/ol/render/canvas/canvasreplay.js @@ -109,6 +109,12 @@ ol.render.canvas.Replay = function(pixelRatio, tolerance) { */ this.extent_ = ol.extent.createEmpty(); + /** + * @private + * @type {!goog.vec.Mat4.Number} + */ + this.tmpLocalTransform_ = goog.vec.Mat4.createNumber(); + }; @@ -180,6 +186,7 @@ ol.render.canvas.Replay.prototype.replay_ = var ii = instructions.length; // end of instructions var d; // data index var dd; // end of per-instruction data + var localTransform = this.tmpLocalTransform_; while (i < ii) { var instruction = instructions[i]; var type = /** @type {ol.render.canvas.Instruction} */ (instruction[0]); @@ -219,7 +226,21 @@ ol.render.canvas.Replay.prototype.replay_ = x = (x + 0.5) | 0; y = (y + 0.5) | 0; } + if (scale != 1 || rotation !== 0) { + ol.vec.Mat4.makeTransform2D( + localTransform, x, y, scale, scale, rotation, -x, -y); + context.setTransform( + goog.vec.Mat4.getElement(localTransform, 0, 0), + goog.vec.Mat4.getElement(localTransform, 1, 0), + goog.vec.Mat4.getElement(localTransform, 0, 1), + goog.vec.Mat4.getElement(localTransform, 1, 1), + goog.vec.Mat4.getElement(localTransform, 0, 3), + goog.vec.Mat4.getElement(localTransform, 1, 3)); + } context.drawImage(image, x, y, width, height); + if (scale != 1 || rotation !== 0) { + context.setTransform(1, 0, 0, 1, 0, 0); + } } ++i; } else if (type == ol.render.canvas.Instruction.END_GEOMETRY) { From fe2f028777cc1ad01de33d740e0e03829ffa0d86 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 19 Dec 2013 15:36:24 +0100 Subject: [PATCH 6/7] Sort miscellaneous properties and add rotation and scale --- src/ol/render/canvas/canvasimmediate.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/ol/render/canvas/canvasimmediate.js b/src/ol/render/canvas/canvasimmediate.js index 85b3260a82..17cb36bcea 100644 --- a/src/ol/render/canvas/canvasimmediate.js +++ b/src/ol/render/canvas/canvasimmediate.js @@ -60,11 +60,13 @@ ol.render.canvas.Immediate = function(context, pixelRatio, extent, transform) { * fillStyle: (string|undefined), * strokeStyle: (string|undefined), * lineWidth: (number|undefined), + * image: (HTMLCanvasElement|HTMLVideoElement|Image), * anchorX: (number|undefined), * anchorY: (number|undefined), - * image: (HTMLCanvasElement|HTMLVideoElement|Image), * height: (number|undefined), * width: (number|undefined), + * scale: number, + * rotation: number, * lineCap: (string|undefined), * lineDash: Array., * lineJoin: (string|undefined), @@ -83,10 +85,12 @@ ol.render.canvas.Immediate = function(context, pixelRatio, extent, transform) { fillStyle: undefined, strokeStyle: undefined, lineWidth: undefined, + image: null, anchorX: undefined, anchorY: undefined, - image: null, height: undefined, + rotation: 0, + scale: 1, width: undefined, lineCap: undefined, lineDash: null, @@ -469,12 +473,14 @@ ol.render.canvas.Immediate.prototype.setImageStyle = function(imageStyle) { var image = imageStyle.getImage(1); goog.asserts.assert(!goog.isNull(image)); var state = this.state_; + state.image = image; state.anchorX = anchor[0]; state.anchorY = anchor[1]; - state.image = image; - state.width = size[0]; state.height = size[1]; + state.rotation = imageStyle.getRotation(); + state.scale = imageStyle.getScale(); state.snapToPixel = imageStyle.getSnapToPixel(); + state.width = size[0]; } }; From bfba52aef4faa79719cd1958bce8d2fc771bac6c Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 19 Dec 2013 15:36:55 +0100 Subject: [PATCH 7/7] Add image rotation and scaling to ol.render.canvas.Immediate --- src/ol/render/canvas/canvasimmediate.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/ol/render/canvas/canvasimmediate.js b/src/ol/render/canvas/canvasimmediate.js index 17cb36bcea..9736439c03 100644 --- a/src/ol/render/canvas/canvasimmediate.js +++ b/src/ol/render/canvas/canvasimmediate.js @@ -5,11 +5,13 @@ goog.provide('ol.render.canvas.Immediate'); goog.require('goog.asserts'); +goog.require('goog.vec.Mat4'); goog.require('ol.color'); goog.require('ol.extent'); goog.require('ol.render.IRender'); goog.require('ol.render.canvas'); goog.require('ol.style.Text'); +goog.require('ol.vec.Mat4'); @@ -106,6 +108,12 @@ ol.render.canvas.Immediate = function(context, pixelRatio, extent, transform) { */ this.pixelCoordinates_ = []; + /** + * @private + * @type {!goog.vec.Mat4.Number} + */ + this.tmpLocalTransform_ = goog.vec.Mat4.createNumber(); + }; @@ -126,6 +134,7 @@ ol.render.canvas.Immediate.prototype.drawImages_ = function(geometry) { goog.asserts.assert(goog.isDef(state.width)); var pixelCoordinates = ol.geom.transformSimpleGeometry2D( geometry, this.transform_, this.pixelCoordinates_); + var localTransform = this.tmpLocalTransform_; var i, ii; for (i = 0, ii = pixelCoordinates.length; i < ii; i += 2) { var x = pixelCoordinates[i] - state.anchorX; @@ -134,8 +143,22 @@ ol.render.canvas.Immediate.prototype.drawImages_ = function(geometry) { x = (x + 0.5) | 0; y = (y + 0.5) | 0; } + if (state.scale != 1 || state.rotation !== 0) { + ol.vec.Mat4.makeTransform2D(localTransform, + x, y, state.scale, state.scale, state.rotation, -x, -y); + context.setTransform( + goog.vec.Mat4.getElement(localTransform, 0, 0), + goog.vec.Mat4.getElement(localTransform, 1, 0), + goog.vec.Mat4.getElement(localTransform, 0, 1), + goog.vec.Mat4.getElement(localTransform, 1, 1), + goog.vec.Mat4.getElement(localTransform, 0, 3), + goog.vec.Mat4.getElement(localTransform, 1, 3)); + } context.drawImage(state.image, x, y, state.width, state.height); } + if (state.scale != 1 || state.rotation !== 0) { + context.setTransform(1, 0, 0, 1, 0, 0); + } };