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

236
Visualizações
CanvasRenderingContext2D.globalCompositeOperation is not working on safari

I'm not sure if this CanvasRenderingContext2D.globalCompositeOperation is not really working or working in safari, but I've tested it.

I'm working on a Convert Image to Sketch Image feature using Javascript, and this implementation involves CANVAS API or CanvasRenderingContext2D.globalCompositeOperation to be exact.

To explain the flow, I'm generating two images using the image selected, 1 black and white image, and 1 black and white a with blurred image, and then after, that I'm using this merge function to merge/combine them to have Sketch-drew-image. Check this https://codepen.io/ohyeahhu/pen/RwMVjym, if you are using Chrome of course it will work, but if you are using safari browser the Sketch Image will not work.

The script filter function below is how I convert/generate an Image to a black and white and blurred using CanvasRenderingContext2D.filter in CANVAS API.

Now I know that the CanvasRenderingContext2D.filter doesn't have any support from the safari browser but I've solved that part by using https://github.com/davidenke/context-filter-polyfill thanks to this beautiful suggestion https://stackoverflow.com/a/65843002/17678769

const filter = function(img, filter) {
   let canvas = document.createElement('canvas');
   canvas.width = img.width;
   canvas.height = img.height;
   let ctx = canvas.getContext('2d');
   ctx.filter = filter;
   ctx.drawImage(img, 0, 0, img.width, img.height);
   return canvas;
}

The script below is the one I'm using to create a sketch-like-image. Now the ctx.globalCompositeOperation = 'color-dodge'; line of code supposed to make the image like a Sketch-drew-image but somehow in Safari browsers mobile devices or mac, it is not working.

const merge = function(front, overlay) {
   let canvas = document.createElement('canvas');
   canvas.width = front.width;
   canvas.height = front.height;
   let ctx = canvas.getContext('2d');
   ctx.globalCompositeOperation = 'color-dodge';
   ctx.drawImage(front, 0, 0, canvas.width, canvas.height);
   ctx.drawImage(overlay, 0, 0, canvas.width, canvas.height);
   let img = document.createElement('img');
   img.src = canvas.toDataURL();
   return img;
}

I've read the MDN documentation of CanvasRenderingContext2D.globalCompositeOperation and it says that safari browsers fully supports it.

If that's the case, then I do not know where did I go wrong on this implementation, Did I made a mistake in the implementation? I'm really stuck in this for a day, is there any alternative or solution to this issue/problem?

about 4 years ago · Santiago Gelvez
1 Respostas
Responde à pergunta

0

Yes Safari does support globalCompositeOperation (gCO), they even do have the biggest list of modes they support among all three main browsers (though I found a rendering bug).

The problem lies in your filter polyfill. It probably messed up somewhere when monkeypatching the various methods of the context and broke the gCO (it also broke clearRect).
Seeing how there is no activity on the project I'm not sure you'll be able to have it fixed, but a simple workaround is to let the polyfill know it shouldn't be called on that canvas by setting the __skipFilterPatch property to true on your canvas:

function createCanvas({width, height}) {
  return Object.assign(document.createElement("canvas"), { width, height });
}
function filter(source, filters) {  
  const canvas = createCanvas(source);
  const ctx = canvas.getContext("2d");
  ctx.filter = filters;
  ctx.drawImage(source, 0, 0);
  return canvas;
}
(async() => {
  const blob = await fetch("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/20141025_Shockwave_Truck_Alliance_Air_Show_2014-3.jpg/640px-20141025_Shockwave_Truck_Alliance_Air_Show_2014-3.jpg").then(resp => resp.blob());
  const bmp = await createImageBitmap(blob);
  const gray = filter(bmp, "grayscale(1)");
  const blur = filter(bmp, "grayscale(1) invert(1) blur(5px)");
  const canvas = createCanvas(bmp);
  canvas.__skipFilterPatch = true; // the magic
  const ctx = canvas.getContext("2d");
  ctx.drawImage(gray, 0, 0);
  ctx.globalCompositeOperation = "color-dodge";
  ctx.drawImage(blur, 0, 0);
  document.body.append(canvas);
 })().catch(console.error);
  
<script src="https://cdn.jsdelivr.net/npm/context-filter-polyfill@0.2.4/dist/index.js"></script>

about 4 years ago · Santiago Gelvez 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