Make Icon's color attribute work in ie11

This commit is contained in:
Maximilian Krög
2020-03-21 00:16:46 +01:00
parent f942c482d8
commit fbb0364ea5
2 changed files with 26 additions and 6 deletions

View File

@@ -2,6 +2,6 @@
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg"> <svg width="20" height="20" xmlns="http://www.w3.org/2000/svg">
<g> <g>
<rect width="20" height="20" style="fill:#fff" /> <rect width="20" height="20" style="fill:#fff; stroke-width:4px; stroke:#000" />
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 225 B

View File

@@ -85,15 +85,18 @@ class IconImage extends EventTarget {
/** /**
* @private * @private
* @param {CanvasRenderingContext2D=} context A context with the image already drawn into.
* @return {boolean} The image canvas is tainted. * @return {boolean} The image canvas is tainted.
*/ */
isTainted_() { isTainted_(context) {
if (this.tainted_ === undefined && this.imageState_ === ImageState.LOADED) { if (this.tainted_ === undefined && this.imageState_ === ImageState.LOADED) {
this.tainted_ = false; if (!context) {
const context = createCanvasContext2D(1, 1); context = createCanvasContext2D(1, 1);
try {
context.drawImage(this.image_, 0, 0); context.drawImage(this.image_, 0, 0);
}
try {
context.getImageData(0, 0, 1, 1); context.getImageData(0, 0, 1, 1);
this.tainted_ = false;
} catch (e) { } catch (e) {
this.tainted_ = true; this.tainted_ = true;
} }
@@ -203,7 +206,7 @@ class IconImage extends EventTarget {
* @private * @private
*/ */
replaceColor_() { replaceColor_() {
if (!this.color_ || this.isTainted_()) { if (!this.color_) {
return; return;
} }
@@ -213,6 +216,23 @@ class IconImage extends EventTarget {
const ctx = this.canvas_.getContext('2d'); const ctx = this.canvas_.getContext('2d');
ctx.drawImage(this.image_, 0, 0); ctx.drawImage(this.image_, 0, 0);
if (this.isTainted_(ctx)) {
// Internet explorer 11 marks canvas as tainted if the drawn image is a svg.
// This makes the getImageData function throw a SecurityError.
// The same effect can be achieved with the globalCompositionOperation but
// Internet Explorer 11 does not properly support the multiply operation.
// So this is only used as a fallback. It is still better than having no icon
// at all.
const c = this.color_;
ctx.globalCompositeOperation = 'multiply';
ctx.fillStyle = 'rgb(' + c[0] + ',' + c[1] + ',' + c[2] + ')';
ctx.fillRect(0, 0, this.image_.width, this.image_.height);
ctx.globalCompositeOperation = 'destination-in';
ctx.drawImage(this.image_, 0, 0);
return;
}
const imgData = ctx.getImageData(0, 0, this.image_.width, this.image_.height); const imgData = ctx.getImageData(0, 0, this.image_.width, this.image_.height);
const data = imgData.data; const data = imgData.data;
const r = this.color_[0] / 255.0; const r = this.color_[0] / 255.0;