diff --git a/externs/olx.js b/externs/olx.js index 287acc9a33..d27a5191e2 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -6932,7 +6932,7 @@ olx.style.RegularShapeOptions.prototype.atlasManager; /** - * @typedef {{color: (ol.Color|string|undefined), + * @typedef {{color: (ol.Color|ol.ColorLike|undefined), * lineCap: (string|undefined), * lineJoin: (string|undefined), * lineDash: (Array.|undefined), @@ -6943,9 +6943,10 @@ olx.style.StrokeOptions; /** - * Color. See {@link ol.color} for possible formats. Default null; if null, - * the Canvas/renderer default black will be used. - * @type {ol.Color|string|undefined} + * A color, gradient or pattern. See {@link ol.color} + * and {@link ol.colorlike} for possible formats. Default null; + * if null, the Canvas/renderer default black will be used. + * @type {ol.Color|ol.ColorLike|undefined} * @api */ olx.style.StrokeOptions.prototype.color; diff --git a/src/ol/render/canvas/immediate.js b/src/ol/render/canvas/immediate.js index 813ee652a4..7a97a0ac23 100644 --- a/src/ol/render/canvas/immediate.js +++ b/src/ol/render/canvas/immediate.js @@ -6,7 +6,6 @@ goog.provide('ol.render.canvas.Immediate'); goog.require('ol'); goog.require('ol.array'); -goog.require('ol.color'); goog.require('ol.colorlike'); goog.require('ol.extent'); goog.require('ol.geom.GeometryType'); @@ -841,7 +840,7 @@ ol.render.canvas.Immediate.prototype.setFillStrokeStyle = function(fillStyle, st strokeStyleWidth : ol.render.canvas.defaultLineWidth), miterLimit: strokeStyleMiterLimit !== undefined ? strokeStyleMiterLimit : ol.render.canvas.defaultMiterLimit, - strokeStyle: ol.color.asString(strokeStyleColor ? + strokeStyle: ol.colorlike.asColorLike(strokeStyleColor ? strokeStyleColor : ol.render.canvas.defaultStrokeStyle) }; } @@ -921,7 +920,7 @@ ol.render.canvas.Immediate.prototype.setTextStyle = function(textStyle) { textStrokeStyleWidth : ol.render.canvas.defaultLineWidth, miterLimit: textStrokeStyleMiterLimit !== undefined ? textStrokeStyleMiterLimit : ol.render.canvas.defaultMiterLimit, - strokeStyle: ol.color.asString(textStrokeStyleColor ? + strokeStyle: ol.colorlike.asColorLike(textStrokeStyleColor ? textStrokeStyleColor : ol.render.canvas.defaultStrokeStyle) }; } diff --git a/src/ol/render/canvas/linestringreplay.js b/src/ol/render/canvas/linestringreplay.js index 83ccbc483b..85d981b6ad 100644 --- a/src/ol/render/canvas/linestringreplay.js +++ b/src/ol/render/canvas/linestringreplay.js @@ -2,7 +2,7 @@ goog.provide('ol.render.canvas.LineStringReplay'); goog.require('ol'); goog.require('ol.array'); -goog.require('ol.color'); +goog.require('ol.colorlike'); goog.require('ol.extent'); goog.require('ol.render.canvas'); goog.require('ol.render.canvas.Instruction'); @@ -30,14 +30,14 @@ ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution, o /** * @private - * @type {{currentStrokeStyle: (string|undefined), + * @type {{currentStrokeStyle: (ol.ColorLike|undefined), * currentLineCap: (string|undefined), * currentLineDash: Array., * currentLineJoin: (string|undefined), * currentLineWidth: (number|undefined), * currentMiterLimit: (number|undefined), * lastStroke: number, - * strokeStyle: (string|undefined), + * strokeStyle: (ol.ColorLike|undefined), * lineCap: (string|undefined), * lineDash: Array., * lineJoin: (string|undefined), @@ -223,7 +223,7 @@ ol.render.canvas.LineStringReplay.prototype.setFillStrokeStyle = function(fillSt ol.DEBUG && console.assert(!fillStyle, 'fillStyle should be null'); ol.DEBUG && console.assert(strokeStyle, 'strokeStyle should not be null'); var strokeStyleColor = strokeStyle.getColor(); - this.state_.strokeStyle = ol.color.asString(strokeStyleColor ? + this.state_.strokeStyle = ol.colorlike.asColorLike(strokeStyleColor ? strokeStyleColor : ol.render.canvas.defaultStrokeStyle); var strokeStyleLineCap = strokeStyle.getLineCap(); this.state_.lineCap = strokeStyleLineCap !== undefined ? diff --git a/src/ol/render/canvas/polygonreplay.js b/src/ol/render/canvas/polygonreplay.js index 5d93591df8..6ad5d826b2 100644 --- a/src/ol/render/canvas/polygonreplay.js +++ b/src/ol/render/canvas/polygonreplay.js @@ -32,14 +32,14 @@ ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution, over /** * @private * @type {{currentFillStyle: (ol.ColorLike|undefined), - * currentStrokeStyle: (string|undefined), + * currentStrokeStyle: (ol.ColorLike|undefined), * currentLineCap: (string|undefined), * currentLineDash: Array., * currentLineJoin: (string|undefined), * currentLineWidth: (number|undefined), * currentMiterLimit: (number|undefined), * fillStyle: (ol.ColorLike|undefined), - * strokeStyle: (string|undefined), + * strokeStyle: (ol.ColorLike|undefined), * lineCap: (string|undefined), * lineDash: Array., * lineJoin: (string|undefined), @@ -296,7 +296,7 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyle = function(fillStyle } if (strokeStyle) { var strokeStyleColor = strokeStyle.getColor(); - state.strokeStyle = ol.color.asString(strokeStyleColor ? + state.strokeStyle = ol.colorlike.asColorLike(strokeStyleColor ? strokeStyleColor : ol.render.canvas.defaultStrokeStyle); var strokeStyleLineCap = strokeStyle.getLineCap(); state.lineCap = strokeStyleLineCap !== undefined ? diff --git a/src/ol/render/canvas/replay.js b/src/ol/render/canvas/replay.js index 2136448a2b..a71efeedc9 100644 --- a/src/ol/render/canvas/replay.js +++ b/src/ol/render/canvas/replay.js @@ -476,8 +476,8 @@ ol.render.canvas.Replay.prototype.replay_ = function( ++i; break; case ol.render.canvas.Instruction.SET_STROKE_STYLE: - ol.DEBUG && console.assert(typeof instruction[1] === 'string', - '2nd instruction should be a string'); + ol.DEBUG && console.assert(ol.colorlike.isColorLike(instruction[1]), + '2nd instruction should be a string, CanvasPattern, or CanvasGradient'); ol.DEBUG && console.assert(typeof instruction[2] === 'number', '3rd instruction should be a number'); ol.DEBUG && console.assert(typeof instruction[3] === 'string', @@ -495,7 +495,7 @@ ol.render.canvas.Replay.prototype.replay_ = function( context.stroke(); pendingStroke = 0; } - context.strokeStyle = /** @type {string} */ (instruction[1]); + context.strokeStyle = /** @type {ol.ColorLike} */ (instruction[1]); context.lineWidth = usePixelRatio ? lineWidth * pixelRatio : lineWidth; context.lineCap = /** @type {string} */ (instruction[3]); context.lineJoin = /** @type {string} */ (instruction[4]); diff --git a/src/ol/render/canvas/textreplay.js b/src/ol/render/canvas/textreplay.js index ba2794f6b4..6f5c971161 100644 --- a/src/ol/render/canvas/textreplay.js +++ b/src/ol/render/canvas/textreplay.js @@ -1,7 +1,6 @@ goog.provide('ol.render.canvas.TextReplay'); goog.require('ol'); -goog.require('ol.color'); goog.require('ol.colorlike'); goog.require('ol.render.canvas'); goog.require('ol.render.canvas.Instruction'); @@ -267,7 +266,7 @@ ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) { textStrokeStyleWidth : ol.render.canvas.defaultLineWidth; var miterLimit = textStrokeStyleMiterLimit !== undefined ? textStrokeStyleMiterLimit : ol.render.canvas.defaultMiterLimit; - var strokeStyle = ol.color.asString(textStrokeStyleColor ? + var strokeStyle = ol.colorlike.asColorLike(textStrokeStyleColor ? textStrokeStyleColor : ol.render.canvas.defaultStrokeStyle); if (!this.textStrokeState_) { this.textStrokeState_ = { diff --git a/src/ol/style/circle.js b/src/ol/style/circle.js index 885acfb4ac..484b75c371 100644 --- a/src/ol/style/circle.js +++ b/src/ol/style/circle.js @@ -260,7 +260,7 @@ ol.style.Circle.prototype.render_ = function(atlasManager) { var strokeWidth = 0; if (this.stroke_) { - strokeStyle = ol.color.asString(this.stroke_.getColor()); + strokeStyle = ol.colorlike.asColorLike(this.stroke_.getColor()); strokeWidth = this.stroke_.getWidth(); if (strokeWidth === undefined) { strokeWidth = ol.render.canvas.defaultLineWidth; diff --git a/src/ol/style/regularshape.js b/src/ol/style/regularshape.js index 92b95c47b0..d6e19b8566 100644 --- a/src/ol/style/regularshape.js +++ b/src/ol/style/regularshape.js @@ -1,7 +1,6 @@ goog.provide('ol.style.RegularShape'); goog.require('ol'); -goog.require('ol.color'); goog.require('ol.colorlike'); goog.require('ol.dom'); goog.require('ol.has'); @@ -329,7 +328,7 @@ ol.style.RegularShape.prototype.render_ = function(atlasManager) { var strokeWidth = 0; if (this.stroke_) { - strokeStyle = ol.color.asString(this.stroke_.getColor()); + strokeStyle = ol.colorlike.asColorLike(this.stroke_.getColor()); strokeWidth = this.stroke_.getWidth(); if (strokeWidth === undefined) { strokeWidth = ol.render.canvas.defaultLineWidth; diff --git a/src/ol/style/stroke.js b/src/ol/style/stroke.js index f90a102452..5d11b69fc3 100644 --- a/src/ol/style/stroke.js +++ b/src/ol/style/stroke.js @@ -1,7 +1,5 @@ goog.provide('ol.style.Stroke'); -goog.require('ol.color'); - /** * @classdesc @@ -20,7 +18,7 @@ ol.style.Stroke = function(opt_options) { /** * @private - * @type {ol.Color|string} + * @type {ol.Color|ol.ColorLike} */ this.color_ = options.color !== undefined ? options.color : null; @@ -82,7 +80,7 @@ ol.style.Stroke.prototype.clone = function() { /** * Get the stroke color. - * @return {ol.Color|string} Color. + * @return {ol.Color|ol.ColorLike} Color. * @api */ ol.style.Stroke.prototype.getColor = function() { @@ -143,7 +141,7 @@ ol.style.Stroke.prototype.getWidth = function() { /** * Set the color. * - * @param {ol.Color|string} color Color. + * @param {ol.Color|ol.ColorLike} color Color. * @api */ ol.style.Stroke.prototype.setColor = function(color) { @@ -223,9 +221,17 @@ ol.style.Stroke.prototype.setWidth = function(width) { */ ol.style.Stroke.prototype.getChecksum = function() { if (this.checksum_ === undefined) { - this.checksum_ = 's' + - (this.color_ ? - ol.color.asString(this.color_) : '-') + ',' + + this.checksum_ = 's'; + if (this.color_) { + if (typeof this.color_ === 'string') { + this.checksum_ += this.color_; + } else { + this.checksum_ += ol.getUid(this.color_).toString(); + } + } else { + this.checksum_ += '-'; + } + this.checksum_ += ',' + (this.lineCap_ !== undefined ? this.lineCap_.toString() : '-') + ',' + (this.lineDash_ ? diff --git a/src/ol/typedefs.js b/src/ol/typedefs.js index e130a9a537..0c0f410a6e 100644 --- a/src/ol/typedefs.js +++ b/src/ol/typedefs.js @@ -75,7 +75,7 @@ ol.CanvasFunctionType; * lineJoin: string, * lineWidth: number, * miterLimit: number, - * strokeStyle: string}} + * strokeStyle: ol.ColorLike}} */ ol.CanvasStrokeState; @@ -95,7 +95,7 @@ ol.CenterConstraintType; /** - * @typedef {{strokeStyle: (string|undefined), strokeWidth: number, + * @typedef {{strokeStyle: (ol.ColorLike|undefined), strokeWidth: number, * size: number, lineDash: Array.}} */ ol.CircleRenderOptions; @@ -112,7 +112,8 @@ ol.Color; /** - * A type accepted by CanvasRenderingContext2D.fillStyle. + * A type accepted by CanvasRenderingContext2D.fillStyle + * or CanvasRenderingContext2D.strokeStyle. * Represents a color, pattern, or gradient. * * @typedef {string|CanvasPattern|CanvasGradient} @@ -405,7 +406,7 @@ ol.RasterOperation; /** * @typedef {{ - * strokeStyle: (string|undefined), + * strokeStyle: (ol.ColorLike|undefined), * strokeWidth: number, * size: number, * lineCap: string, diff --git a/test_rendering/spec/ol/style/expected/polygon-pattern-gradient-canvas.png b/test_rendering/spec/ol/style/expected/polygon-pattern-gradient-canvas.png new file mode 100644 index 0000000000..2f876c299c Binary files /dev/null and b/test_rendering/spec/ol/style/expected/polygon-pattern-gradient-canvas.png differ diff --git a/test_rendering/spec/ol/style/polygon.test.js b/test_rendering/spec/ol/style/polygon.test.js index d9d6845bab..21fd39e093 100644 --- a/test_rendering/spec/ol/style/polygon.test.js +++ b/test_rendering/spec/ol/style/polygon.test.js @@ -260,4 +260,62 @@ describe('ol.rendering.style.Polygon', function() { IMAGE_TOLERANCE, done); }); }); + + describe('CanvasPattern and LinearGradient as fills and strokes', function() { + afterEach(function() { + disposeMap(map); + }); + + function createRainbowGradient() { + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + var gradient = context.createLinearGradient(0,0,30,0); + gradient.addColorStop(0, 'red'); + gradient.addColorStop(1 / 6, 'orange'); + gradient.addColorStop(2 / 6, 'yellow'); + gradient.addColorStop(3 / 6, 'green'); + gradient.addColorStop(4 / 6, 'aqua'); + gradient.addColorStop(5 / 6, 'blue'); + gradient.addColorStop(1, 'purple'); + return gradient; + } + + function createPattern() { + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + canvas.width = 11; + canvas.height = 11; + context.fillStyle = 'rgba(102, 0, 102, 0.5)'; + context.beginPath(); + context.arc(5, 5, 4, 0, 2 * Math.PI); + context.fill(); + context.fillStyle = 'rgb(55, 0, 170)'; + context.beginPath(); + context.arc(5, 5, 2, 0, 2 * Math.PI); + context.fill(); + return context.createPattern(canvas, 'repeat'); + } + + function createFeatures() { + var feature = new ol.Feature({ + geometry: new ol.geom.Polygon([ + [[-20, -20], [-20, 20], [18, 20], [-20, -20]] + ]) + }); + feature.setStyle(new ol.style.Style({ + fill: new ol.style.Fill({color: createPattern()}), + stroke: new ol.style.Stroke({color: createRainbowGradient(), width: 3}) + })); + vectorSource.addFeature(feature); + } + + it('tests the canvas renderer', function(done) { + map = createMap('canvas'); + createFeatures(); + expectResemble( + map, 'spec/ol/style/expected/polygon-pattern-gradient-canvas.png', + 2.75, done); + }); + }); + });