Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

116
Vistas
Different results when applying feColorMatrix SVG filter in CSS or in javascript

Let's say we want to apply a SVG filter on a canvas element. According to this we can apply a SVG filter to the CanvasRenderingContext2D in javascript like this, the filter will only affect shapes drawn after that call:

ctx.filter = "url(#bar)";

We can also just apply the filter in CSS on the whole canvas:

#canvas {
  filter: url(#bar);
}

I need to apply the filter in javascript since I only want part of my canvas to be filtered. When applying a feColorMatrix to some or all of the shapes the results differ depending on the filter having been applied on the 2D Context in JS or on the whole canvas element in CSS.

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.filter = "url(#bar)";
ctx.fillRect(10,10,100,100);
ctx.fillRect(10,120,100,100);
ctx.fillRect(120,10,100,100);
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.ellipse(170, 170, 50, 50, Math.PI / 4, 0, 2 * Math.PI);
ctx.fill();
#canvas {
  /* remove comment to see difference */
  /* filter: url(#bar); */
}
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <filter id="bar">
      <fegaussianblur in="SourceGraphic" stdDeviation="10" result="blur"></fegaussianblur>
      <fecolormatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -7"></fecolormatrix>
    </filter>
  </defs>
</svg>
<canvas id="canvas" width="400" height="400"></canvas>

When you remove the comment that applies the SVG filter on the whole canvas it gives this great gooey effect, I can't seem to achieve that effect only with JS. What am I missing here, shouldn't the two methods give the same result?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

The CSS filter applies on the canvas image as a whole. This is fundamentally different than in your JS code where you apply the filter on each rectangle separately.

Take for instance this code where I draw rectangles with some transparency. Each rectangle on the left side is drawn one by one, while the ones on the right side are all drawn in a single draw operation. You can see how the globalAlpha didn't produce the same result at all.

const ctx = document.querySelector("canvas").getContext("2d");

ctx.globalAlpha = 0.25;
for(let y = 0; y<150; y+=10) {
  // draws each rectangle one after the other
  ctx.fillRect(0, 0, 50, y);
}
for(let y = 0; y<150; y+=10) {
  ctx.rect(100, 0, 50, y);
}
// draws all the right-side rectangles in one go
ctx.fill();
<canvas></canvas>

Well, exactly the same thing happens with the filter.
To get the same effect, draw all your rectangles once and then redraw the canvas over itself with the filter so that it applies to the whole image.

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

ctx.fillRect(10,10,100,100);
ctx.fillRect(10,120,100,100);
ctx.fillRect(120,10,100,100);
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.ellipse(170, 170, 50, 50, Math.PI / 4, 0, 2 * Math.PI);
ctx.fill();
ctx.filter = "url(#bar)";
// clears what was there, alternatively we could have used a second canvas
ctx.globalCompositeOperation = "copy";
ctx.drawImage(canvas, 0, 0);
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position:absolute;z-index:-1">
  <defs>
    <filter id="bar">
      <fegaussianblur in="SourceGraphic" stdDeviation="10" result="blur"></fegaussianblur>
      <fecolormatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -7"></fecolormatrix>
    </filter>
  </defs>
</svg>
<canvas id="canvas" width="400" height="400"></canvas>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda