diff --git a/src/ol/style/circle.js b/src/ol/style/circle.js index b06a8cbada..6b67d83920 100644 --- a/src/ol/style/circle.js +++ b/src/ol/style/circle.js @@ -1,13 +1,7 @@ goog.provide('ol.style.Circle'); goog.require('ol'); -goog.require('ol.color'); -goog.require('ol.colorlike'); -goog.require('ol.dom'); -goog.require('ol.has'); -goog.require('ol.Image'); -goog.require('ol.render.canvas'); -goog.require('ol.style.Image'); +goog.require('ol.style.RegularShape'); /** @@ -16,108 +10,29 @@ goog.require('ol.style.Image'); * * @constructor * @param {olx.style.CircleOptions=} opt_options Options. - * @extends {ol.style.Image} + * @extends {ol.style.RegularShape} * @api */ ol.style.Circle = function(opt_options) { var options = opt_options || {}; - /** - * @private - * @type {ol.style.AtlasManager|undefined} - */ - this.atlasManager_ = options.atlasManager; - - /** - * @private - * @type {Array.} - */ - this.checksums_ = null; - - /** - * @private - * @type {HTMLCanvasElement} - */ - this.canvas_ = null; - - /** - * @private - * @type {HTMLCanvasElement} - */ - this.hitDetectionCanvas_ = null; - - /** - * @private - * @type {ol.style.Fill} - */ - this.fill_ = options.fill !== undefined ? options.fill : null; - - /** - * @private - * @type {ol.style.Stroke} - */ - this.stroke_ = options.stroke !== undefined ? options.stroke : null; - - /** - * @private - * @type {number} - */ - this.radius_ = options.radius; - - /** - * @private - * @type {Array.} - */ - this.origin_ = [0, 0]; - - /** - * @private - * @type {Array.} - */ - this.anchor_ = null; - - /** - * @private - * @type {ol.Size} - */ - this.size_ = null; - - /** - * @private - * @type {ol.Size} - */ - this.imageSize_ = null; - - /** - * @private - * @type {ol.Size} - */ - this.hitDetectionImageSize_ = null; - - this.render_(this.atlasManager_); - - /** - * @type {boolean} - */ - var snapToPixel = options.snapToPixel !== undefined ? - options.snapToPixel : true; - - ol.style.Image.call(this, { - opacity: 1, - rotateWithView: false, - rotation: 0, - scale: 1, - snapToPixel: snapToPixel + ol.style.RegularShape.call(this, { + points: Infinity, + fill: options.fill, + radius: options.radius, + snapToPixel: options.snapToPixel, + stroke: options.stroke, + atlasManager: options.atlasManager }); }; -ol.inherits(ol.style.Circle, ol.style.Image); +ol.inherits(ol.style.Circle, ol.style.RegularShape); /** - * Clones the style. If an atlasmanger was provided to the original style it will be used in the cloned style, too. - * @return {ol.style.Image} The cloned style. + * Clones the style. If an atlasmanager was provided to the original style it will be used in the cloned style, too. + * @return {ol.style.Circle} The cloned style. * @api */ ol.style.Circle.prototype.clone = function() { @@ -134,103 +49,6 @@ ol.style.Circle.prototype.clone = function() { }; -/** - * @inheritDoc - */ -ol.style.Circle.prototype.getAnchor = function() { - return this.anchor_; -}; - - -/** - * Get the fill style for the circle. - * @return {ol.style.Fill} Fill style. - * @api - */ -ol.style.Circle.prototype.getFill = function() { - return this.fill_; -}; - - -/** - * @inheritDoc - */ -ol.style.Circle.prototype.getHitDetectionImage = function(pixelRatio) { - return this.hitDetectionCanvas_; -}; - - -/** - * Get the image used to render the circle. - * @param {number} pixelRatio Pixel ratio. - * @return {HTMLCanvasElement} Canvas element. - * @api - */ -ol.style.Circle.prototype.getImage = function(pixelRatio) { - return this.canvas_; -}; - - -/** - * @inheritDoc - */ -ol.style.Circle.prototype.getImageState = function() { - return ol.Image.State.LOADED; -}; - - -/** - * @inheritDoc - */ -ol.style.Circle.prototype.getImageSize = function() { - return this.imageSize_; -}; - - -/** - * @inheritDoc - */ -ol.style.Circle.prototype.getHitDetectionImageSize = function() { - return this.hitDetectionImageSize_; -}; - - -/** - * @inheritDoc - */ -ol.style.Circle.prototype.getOrigin = function() { - return this.origin_; -}; - - -/** - * Get the circle radius. - * @return {number} Radius. - * @api - */ -ol.style.Circle.prototype.getRadius = function() { - return this.radius_; -}; - - -/** - * @inheritDoc - */ -ol.style.Circle.prototype.getSize = function() { - return this.size_; -}; - - -/** - * Get the stroke style for the circle. - * @return {ol.style.Stroke} Stroke style. - * @api - */ -ol.style.Circle.prototype.getStroke = function() { - return this.stroke_; -}; - - /** * Set the circle radius. * @@ -241,217 +59,3 @@ ol.style.Circle.prototype.setRadius = function(radius) { this.radius_ = radius; this.render_(this.atlasManager_); }; - - -/** - * @inheritDoc - */ -ol.style.Circle.prototype.listenImageChange = ol.nullFunction; - - -/** - * @inheritDoc - */ -ol.style.Circle.prototype.load = ol.nullFunction; - - -/** - * @inheritDoc - */ -ol.style.Circle.prototype.unlistenImageChange = ol.nullFunction; - - -/** - * @private - * @param {ol.style.AtlasManager|undefined} atlasManager An atlas manager. - */ -ol.style.Circle.prototype.render_ = function(atlasManager) { - var imageSize; - var lineDash = null; - var strokeStyle; - var strokeWidth = 0; - - if (this.stroke_) { - strokeStyle = ol.colorlike.asColorLike(this.stroke_.getColor()); - strokeWidth = this.stroke_.getWidth(); - if (strokeWidth === undefined) { - strokeWidth = ol.render.canvas.defaultLineWidth; - } - lineDash = this.stroke_.getLineDash(); - if (!ol.has.CANVAS_LINE_DASH) { - lineDash = null; - } - } - - - var size = 2 * (this.radius_ + strokeWidth) + 1; - - /** @type {ol.CircleRenderOptions} */ - var renderOptions = { - strokeStyle: strokeStyle, - strokeWidth: strokeWidth, - size: size, - lineDash: lineDash - }; - - if (atlasManager === undefined) { - // no atlas manager is used, create a new canvas - var context = ol.dom.createCanvasContext2D(size, size); - this.canvas_ = context.canvas; - - // canvas.width and height are rounded to the closest integer - size = this.canvas_.width; - imageSize = size; - - // draw the circle on the canvas - this.draw_(renderOptions, context, 0, 0); - - this.createHitDetectionCanvas_(renderOptions); - } else { - // an atlas manager is used, add the symbol to an atlas - size = Math.round(size); - - var hasCustomHitDetectionImage = !this.fill_; - var renderHitDetectionCallback; - if (hasCustomHitDetectionImage) { - // render the hit-detection image into a separate atlas image - renderHitDetectionCallback = - this.drawHitDetectionCanvas_.bind(this, renderOptions); - } - - var id = this.getChecksum(); - var info = atlasManager.add( - id, size, size, this.draw_.bind(this, renderOptions), - renderHitDetectionCallback); - ol.DEBUG && console.assert(info, 'circle radius is too large'); - - this.canvas_ = info.image; - this.origin_ = [info.offsetX, info.offsetY]; - imageSize = info.image.width; - - if (hasCustomHitDetectionImage) { - this.hitDetectionCanvas_ = info.hitImage; - this.hitDetectionImageSize_ = - [info.hitImage.width, info.hitImage.height]; - } else { - this.hitDetectionCanvas_ = this.canvas_; - this.hitDetectionImageSize_ = [imageSize, imageSize]; - } - } - - this.anchor_ = [size / 2, size / 2]; - this.size_ = [size, size]; - this.imageSize_ = [imageSize, imageSize]; -}; - - -/** - * @private - * @param {ol.CircleRenderOptions} renderOptions Render options. - * @param {CanvasRenderingContext2D} context The rendering context. - * @param {number} x The origin for the symbol (x). - * @param {number} y The origin for the symbol (y). - */ -ol.style.Circle.prototype.draw_ = function(renderOptions, context, x, y) { - // reset transform - context.setTransform(1, 0, 0, 1, 0, 0); - - // then move to (x, y) - context.translate(x, y); - - context.beginPath(); - context.arc( - renderOptions.size / 2, renderOptions.size / 2, - this.radius_, 0, 2 * Math.PI, true); - - if (this.fill_) { - context.fillStyle = ol.colorlike.asColorLike(this.fill_.getColor()); - context.fill(); - } - if (this.stroke_) { - context.strokeStyle = renderOptions.strokeStyle; - context.lineWidth = renderOptions.strokeWidth; - if (renderOptions.lineDash) { - context.setLineDash(renderOptions.lineDash); - } - context.stroke(); - } - context.closePath(); -}; - - -/** - * @private - * @param {ol.CircleRenderOptions} renderOptions Render options. - */ -ol.style.Circle.prototype.createHitDetectionCanvas_ = function(renderOptions) { - this.hitDetectionImageSize_ = [renderOptions.size, renderOptions.size]; - if (this.fill_) { - this.hitDetectionCanvas_ = this.canvas_; - return; - } - - // if no fill style is set, create an extra hit-detection image with a - // default fill style - var context = ol.dom.createCanvasContext2D(renderOptions.size, renderOptions.size); - this.hitDetectionCanvas_ = context.canvas; - - this.drawHitDetectionCanvas_(renderOptions, context, 0, 0); -}; - - -/** - * @private - * @param {ol.CircleRenderOptions} renderOptions Render options. - * @param {CanvasRenderingContext2D} context The context. - * @param {number} x The origin for the symbol (x). - * @param {number} y The origin for the symbol (y). - */ -ol.style.Circle.prototype.drawHitDetectionCanvas_ = function(renderOptions, context, x, y) { - // reset transform - context.setTransform(1, 0, 0, 1, 0, 0); - - // then move to (x, y) - context.translate(x, y); - - context.beginPath(); - context.arc( - renderOptions.size / 2, renderOptions.size / 2, - this.radius_, 0, 2 * Math.PI, true); - - context.fillStyle = ol.color.asString(ol.render.canvas.defaultFillStyle); - context.fill(); - if (this.stroke_) { - context.strokeStyle = renderOptions.strokeStyle; - context.lineWidth = renderOptions.strokeWidth; - if (renderOptions.lineDash) { - context.setLineDash(renderOptions.lineDash); - } - context.stroke(); - } - context.closePath(); -}; - - -/** - * @return {string} The checksum. - */ -ol.style.Circle.prototype.getChecksum = function() { - var strokeChecksum = this.stroke_ ? - this.stroke_.getChecksum() : '-'; - var fillChecksum = this.fill_ ? - this.fill_.getChecksum() : '-'; - - var recalculate = !this.checksums_ || - (strokeChecksum != this.checksums_[1] || - fillChecksum != this.checksums_[2] || - this.radius_ != this.checksums_[3]); - - if (recalculate) { - var checksum = 'c' + strokeChecksum + fillChecksum + - (this.radius_ !== undefined ? this.radius_.toString() : '-'); - this.checksums_ = [checksum, strokeChecksum, fillChecksum, this.radius_]; - } - - return this.checksums_[0]; -}; diff --git a/src/ol/style/regularshape.js b/src/ol/style/regularshape.js index d6e19b8566..d4003836e7 100644 --- a/src/ol/style/regularshape.js +++ b/src/ol/style/regularshape.js @@ -63,7 +63,7 @@ ol.style.RegularShape = function(options) { this.points_ = options.points; /** - * @private + * @protected * @type {number} */ this.radius_ = /** @type {number} */ (options.radius !== undefined ? @@ -113,7 +113,7 @@ ol.style.RegularShape = function(options) { this.hitDetectionImageSize_ = null; /** - * @private + * @protected * @type {ol.style.AtlasManager|undefined} */ this.atlasManager_ = options.atlasManager; @@ -145,7 +145,7 @@ ol.inherits(ol.style.RegularShape, ol.style.Image); /** - * Clones the style. If an atlasmanger was provided to the original style it will be used in the cloned style, too. + * Clones the style. If an atlasmanager was provided to the original style it will be used in the cloned style, too. * @return {ol.style.RegularShape} The cloned style. * @api */ @@ -315,7 +315,7 @@ ol.style.RegularShape.prototype.unlistenImageChange = ol.nullFunction; /** - * @private + * @protected * @param {ol.style.AtlasManager|undefined} atlasManager An atlas manager. */ ol.style.RegularShape.prototype.render_ = function(atlasManager) { @@ -430,16 +430,24 @@ ol.style.RegularShape.prototype.draw_ = function(renderOptions, context, x, y) { context.translate(x, y); context.beginPath(); - if (this.radius2_ !== this.radius_) { - this.points_ = 2 * this.points_; - } - for (i = 0; i <= this.points_; i++) { - angle0 = i * 2 * Math.PI / this.points_ - Math.PI / 2 + this.angle_; - radiusC = i % 2 === 0 ? this.radius_ : this.radius2_; - context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0), - renderOptions.size / 2 + radiusC * Math.sin(angle0)); + + if (this.points_ === Infinity) { + context.arc( + renderOptions.size / 2, renderOptions.size / 2, + this.radius_, 0, 2 * Math.PI, true); + } else { + if (this.radius2_ !== this.radius_) { + this.points_ = 2 * this.points_; + } + for (i = 0; i <= this.points_; i++) { + angle0 = i * 2 * Math.PI / this.points_ - Math.PI / 2 + this.angle_; + radiusC = i % 2 === 0 ? this.radius_ : this.radius2_; + context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0), + renderOptions.size / 2 + radiusC * Math.sin(angle0)); + } } + if (this.fill_) { context.fillStyle = ol.colorlike.asColorLike(this.fill_.getColor()); context.fill(); @@ -494,15 +502,22 @@ ol.style.RegularShape.prototype.drawHitDetectionCanvas_ = function(renderOptions context.translate(x, y); context.beginPath(); - if (this.radius2_ !== this.radius_) { - this.points_ = 2 * this.points_; - } - var i, radiusC, angle0; - for (i = 0; i <= this.points_; i++) { - angle0 = i * 2 * Math.PI / this.points_ - Math.PI / 2 + this.angle_; - radiusC = i % 2 === 0 ? this.radius_ : this.radius2_; - context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0), - renderOptions.size / 2 + radiusC * Math.sin(angle0)); + + if (this.points_ === Infinity) { + context.arc( + renderOptions.size / 2, renderOptions.size / 2, + this.radius_, 0, 2 * Math.PI, true); + } else { + if (this.radius2_ !== this.radius_) { + this.points_ = 2 * this.points_; + } + var i, radiusC, angle0; + for (i = 0; i <= this.points_; i++) { + angle0 = i * 2 * Math.PI / this.points_ - Math.PI / 2 + this.angle_; + radiusC = i % 2 === 0 ? this.radius_ : this.radius2_; + context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0), + renderOptions.size / 2 + radiusC * Math.sin(angle0)); + } } context.fillStyle = ol.render.canvas.defaultFillStyle;