From 38ecaa9814408fdaf6d141bd147a200ca996659b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Fri, 27 Mar 2020 20:38:53 +0100 Subject: [PATCH] Use compositing operation for icon colorization when possible. --- src/ol/style/IconImage.js | 40 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/ol/style/IconImage.js b/src/ol/style/IconImage.js index e5a921c823..ba4f96f479 100644 --- a/src/ol/style/IconImage.js +++ b/src/ol/style/IconImage.js @@ -232,37 +232,31 @@ class IconImage extends EventTarget { ctx.scale(pixelRatio, pixelRatio); ctx.drawImage(this.image_, 0, 0); - if (this.isTainted_()) { - // If reading from the canvas throws a SecurityError the same effect can be - // achieved with globalCompositeOperation. - // This could be used as the default, but it is not fully supported by all - // browsers. E. g. Internet Explorer 11 does not support the multiply - // operation and the resulting image shape will be completelly filled with - // the provided color. - // So this is only used as a fallback. It is still better than having no icon - // at all. + ctx.globalCompositeOperation = 'multiply'; + // Internet Explorer 11 does not support the multiply operation. + // If the canvas is tainted in Internet Explorer this still produces + // a solid color image with the shape of the icon. + if (ctx.globalCompositeOperation === 'multiply' || this.isTainted_()) { const c = this.color_; - ctx.globalCompositeOperation = 'multiply'; ctx.fillStyle = 'rgb(' + c[0] + ',' + c[1] + ',' + c[2] + ')'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.globalCompositeOperation = 'destination-in'; ctx.drawImage(this.image_, 0, 0); - return; - } + } else { + const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); + const data = imgData.data; + const r = this.color_[0] / 255.0; + const g = this.color_[1] / 255.0; + const b = this.color_[2] / 255.0; - const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); - const data = imgData.data; - const r = this.color_[0] / 255.0; - const g = this.color_[1] / 255.0; - const b = this.color_[2] / 255.0; - - for (let i = 0, ii = data.length; i < ii; i += 4) { - data[i] *= r; - data[i + 1] *= g; - data[i + 2] *= b; + for (let i = 0, ii = data.length; i < ii; i += 4) { + data[i] *= r; + data[i + 1] *= g; + data[i + 2] *= b; + } + ctx.putImageData(imgData, 0, 0); } - ctx.putImageData(imgData, 0, 0); } /**