In Chromium-based browsers (I'm using brave), canvas
is rendering this way:
But in Firefox, for some reason, it's rendering this way:
Here is the method I'm using:
context.drawImage(image, 100, 100, 100, 400);
I'm not using any CSS on the canvas
element, just this:
html,
body {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
And this to resize and append the canvas
:
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
export const graphics = canvas.getContext("2d");
const adaptResolution = () => {
canvas.width = innerWidth;
canvas.height = innerHeight;
};
adaptResolution();
addEventListener("resize", adaptResolution);
Can I make the Firefox's canvas
behave the same as in Chromium-based browsers? What is causing this difference and how can I fix it?
This is the SVG I'm trying to render on screen:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="768"
height="576"
viewBox="0 0 203.2 152.4"
version="1.1"
id="svg5"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="box.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="false"
units="px"
inkscape:zoom="0.38752104"
inkscape:cx="107.09096"
inkscape:cy="187.08661"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#000000;stroke-width:0.387859"
id="rect31"
width="206.87587"
height="153.6207"
x="-1.7069"
y="-1.7068989" />
</g>
</svg>
CodePudding user response:
This is an interop issue that I already reported on the specs.
Unfortunately it didn't get much traction yet...
The issue is that it's currently unclear on which "image" drawImage
's resizing options should act. Chrome considers that it should treat the input svg at its default size and stretch it, Firefox considers that the resizing options are the output box and will adapt the svg content to this box.
To get Chrome's behavior in Firefox, you can add a preserveAspectRatio="none"
attribute to the root of your SVG image:
const svg = new Blob([`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
preserveAspectRatio="none"
width="768"
height="576"
viewBox="0 0 203.2 152.4"
version="1.1"
id="svg5"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="box.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="false"
units="px"
inkscape:zoom="0.38752104"
inkscape:cx="107.09096"
inkscape:cy="187.08661"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#000000;stroke-width:0.387859"
id="rect31"
width="206.87587"
height="153.6207"
x="-1.7069"
y="-1.7068989" />
</g>
</svg>`], { type:"image/svg xml"});
const img = new Image();
img.src = URL.createObjectURL(svg);
img.onload = e => document.querySelector("canvas").getContext("2d").drawImage(img, 0, 0, 100, 400);
<canvas width="500" height="500"></canvas>