Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

117
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda