This article is suitable for readers who are interested in canvas drawing, graphics, and front-end visualization.
wedgeEverything has a cause.
Recently, the product needs to have such a function: dyeing some graphics. Come to think of it, this is not something that comes easily. I have already studied the technology of graphic dyeing. So I sent the two algorithms I wrote before to my friend and asked him to implement them as a reference. The first algorithm is to manipulate pixels, and the second one uses image synthesis: globalCompositeOperation.
Everything is subject to surprises, especially when writing programs.
Not long after, my friend said that the second algorithm did not work under Firefox.
Explore whyI was shocked when I heard there was a bug. I have tested it, and I have also tested it under FireFox. So I opened Firefox and started the example, and found that it was fine and there was no problem.
But there are problems with integrating small partners into products. What's the difference? After investigating together, I finally discovered that one difference between my sample code and the code in the product is that the sample code uses png images, while the product uses svg images.
Could it be a problem with the svg image? Taking an svg image and putting it in the sample code is indeed wrong. The conclusion is already obvious:
Under the FireFox browser, when drawing SVG images under Canvas, the setting of globalCompositeOperation will not take effect.
The following is a piece of code for testing. ctx.globalCompositeOperation = 'destination-out' means using the shape of the source image to hollow out the destination image.
In other browsers, the following code is valid and hollowed out. But in
Doesn't work under FireFox:
<html><head> <script> function init() { var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); var img = new Image(); img.onload = function () { ctx.drawImage(img, 0, 0, img.width * 2, img.height * 2); ctx.globalCompositeOperation = 'destination-out'; } img.src = 'diffuse.png'; var svg = new Image; svg.src = ./d.svg; function drawPoint(pointX, pointY) { ctx.drawImage(svg , pointX - svg.width / 4, pointY - svg.height / 4, svg.width / 2, svg.height / 2); } canvas.addEventListener('click', function (e) { drawPoint(e.clientX, e.clientY); }, false); } </script></ head><body onload=init(); style=background: red> <div> <canvas id=c width=1000 height=1000></canvas> </div></body></html>How to solve
The cause of the problem is found, and the solution is actually simple.
That's often the case, and often times it's harder to find the problem than to solve it.
The solution is actually very simple
Add a judgment to the code to determine whether the browser is FireFox.
If so, first draw the svg image onto the temporary canvas.
Subsequent drawing uses a temporary canvas to replace the svg image.
For example, the above code can be improved as follows:
function init() { var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); var img = new Image(); img.onload = function () { ctx.drawImage(img , 0, 0, img.width * 2, img.height * 2); ctx.globalCompositeOperation = 'destination-out'; } img.src = 'diffuse.png'; var svg = new Image; svg.src = ./d.svg; var tempCanvas = svg; if(isFirefox){ svg.onload = function() { tempCanvas = document.createElement('canvas'); tempCanvas.width = svg.width; tempCanvas.height = svg.height; var tempCtx = tempCanvas.getContext('2d'); tempCtx.drawImage(svg,0,0,svg.width,svg.height); } } function drawPoint(pointX, pointY) { ctx.drawImage(tempCanvas, pointX - svg.width / 4, pointY - svg.height / 4, svg.width / 2, svg.height / 2); } canvas.addEventListener('click', function (e) { drawPoint(e.clientX, e.clientY ); }, false); }
The above is the entire content of this article. I hope it will be helpful to everyone’s study. I also hope everyone will support VeVb Wulin Network.